import type {
  CollectionDocument,
  TabDocument,
  WorkspaceDocument,
} from "../../database/database";

// Repositories
import { CollectionRepository } from "../../repositories/collection.repository";
import { EnvironmentRepository } from "../../repositories/environment.repository";
import { TabRepository } from "../../repositories/tab.repository";
import { WorkspaceRepository } from "../../repositories/workspace.repository";
//-----
import { v4 as uuidv4 } from "uuid";

//-----
// Services
import {
  insertCollection,
  insertCollectionDirectory,
} from "../../services/collection";
import { CollectionService } from "../../services/collection.service";
import { notifications } from "@sparrow/library/ui";
// import { setContentTypeHeader } from "@sparrow/common/utils";

//-----
//External Imports
import { invoke } from "@tauri-apps/api/core";
//-----

//Utils

import type {
  CreateApiRequestPostBody,
  CreateDirectoryPostBody,
  ImportBodyUrl,
} from "@sparrow/common/dto";

//Emuns

import { ItemType, UntrackedItems } from "@sparrow/common/enums/item-type.enum";
import {
  ContentTypeEnum,
  ResponseStatusCode,
  WorkspaceType,
} from "@sparrow/common/enums";
//-----

import { scrollToTab } from "@sparrow/common/utils/navigation";
import { GuideRepository } from "../../repositories/guide.repository";
import { Events } from "@sparrow/common/enums/mixpanel-events.enum";
import MixpanelEvent from "@app/utils/mixpanel/MixpanelEvent";
import { type Observable } from "rxjs";
import {
  InitMockRequestTab,
  InitRequestTab,
  InitWebSocketTab,
  InitAiRequestTab,
  Sleep,
} from "@sparrow/common/utils";
import { InitCollectionTab } from "@sparrow/common/utils";
import { InitFolderTab } from "@sparrow/common/utils";
import {
  addCollectionItem,
  aiChatBotPanelClose,
  tabsSplitterDirection,
} from "@sparrow/workspaces/stores";
import {
  insertCollectionRequest,
  updateCollectionRequest,
} from "../../services/collection";
import { GithubService } from "../../services/github.service";
import { GithubRepoReposistory } from "../../repositories/github-repo.repository";
import { RequestTabAdapter } from "../../adapter/request-tab";
import { FeatureSwitchRepository } from "../../repositories/feature-switch.repository";
import { GuestUserRepository } from "../../repositories/guest-user.repository";
import { isGuestUserActive } from "@app/store/auth.store";
import { InitTab } from "@sparrow/common/factory";
import {
  type CollectionBaseInterface as CollectionDto,
  type CollectionArgsBaseInterface as CollectionArgsDto,
  type CollectionItemBaseInterface as CollectionItemsDto,
  type MoveRequestArgsDto as MoveRequestArgsDto,
  CollectionItemTypeBaseEnum,
  CollectionTypeBaseEnum,
} from "@sparrow/common/types/workspace/collection-base";
import type { HttpRequestBaseInterface as RequestDto } from "@sparrow/common/types/workspace/http-request-base";
import {
  TabPersistenceTypeEnum,
  type Tab,
  TabTypeEnum,
  type Path as TabPath,
} from "@sparrow/common/types/workspace/tab";
import { type State as WebSocketStateType } from "@sparrow/common/types/workspace/web-socket";
import {
  type EventsValues,
  type State as SocketIOStateType,
} from "@sparrow/common/types/workspace/socket-io-request-tab";
import type {
  GraphqlRequestAuthTabInterface,
  GraphqlRequestAutoGeneratedHeadersTabInterface,
  GraphqlRequestStateTabInterface,
} from "@sparrow/common/types/workspace/graphql-request-tab";
import { SocketTabAdapter } from "../../adapter/socket-tab";
import type { CollectionDocType } from "../../models/collection.model";
import type { GuideQuery } from "../../types/user-guide";
import type { FeatureQuery } from "../../types/feature-switch";
import { ReduceQueryParams } from "@sparrow/workspaces/features/rest-explorer/utils";
import { AiRequestTabAdapter } from "../../adapter";
import { createDeepCopy } from "@sparrow/common/utils";
import {
  CollectionTabAdapter,
  FolderTabAdapter,
  GraphqlTabAdapter,
  RequestMockTabAdapter,
  RequestSavedTabAdapter,
  SocketIoTabAdapter,
} from "../../adapter";
import type {
  SocketIORequestDeletePayloadDtoInterface,
  SocketIORequestCreateUpdateInFolderPayloadDtoInterface,
  SocketIORequestCreateUpdateInCollectionPayloadDtoInterface,
} from "@sparrow/common/types/workspace/socket-io-request-dto";
import { SocketIORequestDefaultAliasBaseEnum } from "@sparrow/common/types/workspace/socket-io-request-base";
import type {
  GraphqlRequestAuthDtoInterface,
  GraphqlRequestCreateUpdateInCollectionPayloadDtoInterface,
  GraphqlRequestCreateUpdateInFolderPayloadDtoInterface,
  GraphqlRequestDeletePayloadDtoInterface,
  GraphqlRequestKeyValueDtoInterface,
} from "@sparrow/common/types/workspace/graphql-request-dto";
import {
  GraphqlRequestDefaultAliasBaseEnum,
  GraphqlRequestAuthModeBaseEnum,
} from "@sparrow/common/types/workspace/graphql-request-base";
import type { Path } from "@sparrow/common/interfaces/request.interface";
import {
  type Body,
  type KeyValueChecked,
  RequestMethodEnum,
  type Auth,
  type StatePartial,
  type State,
  RequestDataTypeEnum,
  RequestDatasetEnum,
} from "@sparrow/common/types/workspace";
import type { CollectionNavigationTabEnum } from "@sparrow/common/types/workspace/collection-tab";
import { WorkspaceService } from "@app/services/workspace.service";
import constants from "@app/constants/constants";
import { HttpResponseSavedBodyModeBaseEnum } from "@sparrow/common/types/workspace/http-request-saved-base";
import { WorkspaceTabAdapter } from "@app/adapter/workspace-tab";
import { navigate } from "svelte-navigator";
import * as Sentry from "@sentry/svelte";
import { MockHistoryTabAdapter } from "@app/adapter/mock-history-tab";
import type {
  AiModelProviderEnum,
  AiRequestBaseInterface,
  AIModelVariant,
} from "@sparrow/common/types/workspace/ai-request-base";
import { TeamRepository } from "@app/repositories/team.repository";
import { TeamService } from "@app/services/team.service";
import { PlanRepository } from "@app/repositories/plan.repository";
import { open } from "@tauri-apps/plugin-shell";
import type { TransformedRequest } from "@sparrow/common/types/workspace/collection-base";
import { getAuthJwt, getSelfhostUrls } from "@app/utils/jwt";
import { get } from "svelte/store";

export default class CollectionsViewModel {
  private tabRepository = new TabRepository();
  private workspaceRepository = new WorkspaceRepository();
  private collectionRepository = new CollectionRepository();
  private environmentRepository = new EnvironmentRepository();
  private githhubRepoRepository = new GithubRepoReposistory();
  private collectionService = new CollectionService();
  private workspaceService = new WorkspaceService();
  private githubService = new GithubService();
  private guideRepository = new GuideRepository();
  private teamRepository = new TeamRepository();
  private teamService = new TeamService();
  private planRepository = new PlanRepository();

  private initTab = new InitTab();

  private featureSwitchRepository = new FeatureSwitchRepository();
  private guestUserRepository = new GuestUserRepository();
  private movedTabStartIndex = 0;
  private movedTabEndIndex = 0;

  constructor() {}

  /**
   * Get the guest user state
   */
  private getGuestUserState = async () => {
    const response = await this.guestUserRepository.findOne({
      name: "guestUser",
    });
    return response?.getLatest().toMutableJSON().isGuestUser;
  };

  /**
   * Fetch collections from services and insert to repository
   * @param workspaceId - id of current workspace
   */
  public fetchCollections = async (
    workspaceId: string,
  ): Promise<{ collectionItemTabsToBeDeleted?: string[] }> => {
    const isGuestUser = await this.getGuestUserState();
    if (!workspaceId || isGuestUser) {
      return {};
    }

    const getCollectionItemIds = (
      collectionItem: any,
      collectedIds: string[],
    ): void => {
      const stack = [collectionItem];
      while (stack.length > 0) {
        const item = stack.pop();
        if (!item) continue;

        if (!item.type) {
          // Collection
          collectedIds.push(item._id);
        } else {
          // Folder, Http Request, WebSocket Request
          collectedIds.push(item.id);
        }

        if (Array.isArray(item.items)) {
          stack.push(...item.items);
        }
      }
    };

    const baseUrl = await this.constructBaseUrl(workspaceId);
    const workspaceData =
      await this.workspaceRepository.readWorkspace(workspaceId);

    let res;
    if (
      workspaceData &&
      workspaceData.workspaceType === WorkspaceType.PUBLIC &&
      workspaceData.isShared
    ) {
      res = await this.collectionService.fetchPublicCollection(
        workspaceId,
        constants.API_URL,
      );
    } else {
      res = await this.collectionService.fetchCollection(workspaceId, baseUrl);
    }

    if (!res?.isSuccessful || !res?.data?.data) {
      return {};
    }

    const collections = res.data.data;
    const processedCollections: any[] = [];
    const collectionIds: string[] = [];

    const chunkSize = 100;
    for (let i = 0; i < collections.length; i += chunkSize) {
      const chunk = collections.slice(i, i + chunkSize);
      for (const col of chunk) {
        const collection = createDeepCopy(col);
        collection.workspaceId = workspaceId;
        collection.id = col._id;
        if (!collection.description) collection.description = "";
        delete collection._id;

        processedCollections.push(collection);
        collectionIds.push(col._id);
      }
      await new Promise((res) => setTimeout(res)); // yield to UI
    }

    await this.collectionRepository.bulkInsertData(
      workspaceId,
      processedCollections,
    );
    await this.collectionRepository.deleteOrphanCollections(
      workspaceId,
      collectionIds,
    );

    const collectionItemIds: string[] = [];
    for (const collection of collections) {
      getCollectionItemIds(collection, collectionItemIds);
    }

    const collectionItemTabsToBeDeleted =
      await this.tabRepository.getIdOfTabsThatDoesntExistAtCollectionLevel(
        workspaceId,
        collectionItemIds,
      );

    return {
      collectionItemTabsToBeDeleted,
    };
  };

  /**
   * @description - refreshes workspace data with sync to mongo server
   * @param workspaceId - workspace Id
   * @returns
   */
  public fetchWorkspace = async (workspaceId: string): Promise<void> => {
    const guestUser = await this.guestUserRepository.findOne({
      name: "guestUser",
    });

    const isGuestUser = guestUser?.getLatest().toMutableJSON().isGuestUser;
    if (isGuestUser) {
      return;
    }

    const baseUrl = await this.constructBaseUrl(workspaceId);
    const workspaceData =
      await this.workspaceRepository.readWorkspace(workspaceId);

    let response;
    if (
      workspaceData &&
      workspaceData.workspaceType === WorkspaceType.PUBLIC &&
      workspaceData.isShared
    ) {
      response = await this.workspaceService.fetchPublicWorkspace(workspaceId);
    } else {
      response = await this.workspaceService.fetchWorkspace(
        workspaceId,
        baseUrl,
      );
    }

    if (!response?.isSuccessful || !response?.data?.data) {
      return;
    }

    const responseWorkspaceData = response.data.data;
    await this.workspaceRepository.updateWorkspace(workspaceId, {
      name: responseWorkspaceData.name,
      description: responseWorkspaceData.description,
    });
    return;
  };

  public deleteTabsWithTabIdInAWorkspace = (
    _workspaceId: string,
    _tabIds: string[],
  ) => {
    this.tabRepository.deleteTabsWithTabIdInAWorkspace(_workspaceId, _tabIds);
  };

  /**
   *
   * @param uuid - workspace id
   * @returns workspace document
   */
  public readWorkspace = (uuid: string): Promise<WorkspaceDocument> => {
    return this.workspaceRepository.readWorkspace(uuid);
  };

  /**
   * Return current tabs list of top tab bar component
   */
  public tabs() {
    return this.tabRepository.getTabList();
  }
  public getTabListWithWorkspaceId(
    workspaceId: string,
  ): Observable<TabDocument[]> | undefined {
    return this.tabRepository.getTabListWithWorkspaceId(workspaceId);
  }

  /**
   * @description - Fetches github repository data
   */
  public getGithubRepo = async () => {
    const githubRepoId = "sparrow-github";
    const document = await this.githhubRepoRepository.findOne({
      id: githubRepoId,
    });
    return document;
  };

  /**
   * Get list of all environments
   * @return Observable<Environments[]> - list of all environments
   */
  public getEnvironmentList = () => {
    return this.environmentRepository.getEnvironment();
  };

  /**
   * Get active tab(if any)
   * @returns :Observable<any> | undefined - active tab
   */
  public getActiveTab = (
    workspaceId: string,
  ): Observable<TabDocument | null> | undefined => {
    return this.tabRepository.getTabWithWorkspaceId(workspaceId);
  };

  /**
   * Handles creating a new tab
   * @param data :any - data of the tab i.e. collection, folder or request
   */
  public handleCreateTab = (data: Tab) => {
    this.tabRepository.createTab(data);
  };

  /**
   * Remove the tab from tab list in store
   * @param id - tab id
   */
  public handleRemoveTab = (id: string) => {
    this.tabRepository.removeTab(id);
  };

  /**
   * Create new tab with untracked id
   */
  public createNewTab = async (_limit = 5) => {
    if (_limit === 0) return;
    const ws = await this.workspaceRepository.getActiveWorkspaceDoc();
    if (ws) {
      const initRequestTab = new InitRequestTab(
        "UNTRACKED-" + uuidv4(),
        ws._id,
      );
      const aiPanelState = get(aiChatBotPanelClose);
      initRequestTab.updateChatbotState(aiPanelState);
      this.tabRepository.createTab(initRequestTab.getValue());
      scrollToTab("");
      MixpanelEvent(Events.ADD_NEW_API_REQUEST, { source: "TabBar" });
    } else {
      setTimeout(() => {
        this.createNewTab(_limit - 1);
      }, 2000);
    }
  };

  /**
   * Create new tab with untracked id with updated Details
   */
  public createNewTabWithData = async (_limit = 5) => {
    if (_limit === 0) return;
    const ws = await this.workspaceRepository.getActiveWorkspaceDoc();
    // isApiCreatedFirstTime.set(true);
    if (ws) {
      const initRequestTab = new InitRequestTab(
        "UNTRACKED-" + uuidv4(),
        ws._id,
      );
      initRequestTab.updateChatbotState(true);
      this.tabRepository.createTab(initRequestTab.getValue());
      scrollToTab("");
    } else {
      setTimeout(() => {
        this.createNewTabWithData(_limit - 1);
      }, 2000);
    }
  };

  /**
   * Create web socket new tab with untracked id
   */
  private createWebSocketNewTab = async () => {
    const ws = await this.workspaceRepository.getActiveWorkspaceDoc();
    if (ws) {
      this.tabRepository.createTab(
        this.initTab.webSocket("UNTRACKED-" + uuidv4(), ws._id).getValue(),
      );
      scrollToTab("");
      MixpanelEvent(Events.ADD_NEW_API_REQUEST, { source: "TabBar" });
    } else {
      console.error("No active workspace found!");
    }
  };

  /**
   * Create socket io new tab with untracked id
   */
  private createSocketIoNewTab = async () => {
    const ws = await this.workspaceRepository.getActiveWorkspaceDoc();
    if (ws) {
      this.tabRepository.createTab(
        this.initTab.socketIo("UNTRACKED-" + uuidv4(), ws._id).getValue(),
      );
      scrollToTab("");
    } else {
      console.error("No active workspace found!");
    }
  };

  /**
   * Create graphql new tab with untracked id
   */
  private createGraphqlNewTab = async () => {
    const ws = await this.workspaceRepository.getActiveWorkspaceDoc();
    if (ws) {
      this.tabRepository.createTab(
        this.initTab.graphQl("UNTRACKED-" + uuidv4(), ws._id).getValue(),
      );
      scrollToTab("");
    } else {
      console.error("No active workspace found!");
    }
  };

  /**
   * Create ai request new tab with untracked id
   */
  private createAiRequestNewTab = async () => {
    const ws = await this.workspaceRepository.getActiveWorkspaceDoc();
    if (ws) {
      this.tabRepository.createTab(
        this.initTab.aiRequest("UNTRACKED-" + uuidv4(), ws._id).getValue(),
      );
      scrollToTab("");
    } else {
      console.error("No active workspace found!");
    }
  };

  // ****** Handling Tab Duplication - St ******
  private createRESTDuplciateTab = async (tabId: string) => {
    const originalTab = await this.tabRepository.getTabById(tabId); // Tab to be copied
    const currWorkSpace =
      await this.workspaceRepository.getActiveWorkspaceDoc();

    if (currWorkSpace) {
      const newRequestTab = this.initTab.request(
        "UNTRACKED-" + uuidv4(),
        currWorkSpace._id,
      );
      MixpanelEvent(Events.ADD_NEW_API_REQUEST, { source: "TabBar" });

      // Copy values using setter methods (excluding id, tabId, and timestamp)
      const { id, tabId, timestamp, ...restOfData } =
        originalTab.toMutableJSON();

      newRequestTab.updateName(restOfData.name);
      newRequestTab.updateDescription(restOfData.description);
      newRequestTab.updateUrl(restOfData.property.request.url);
      newRequestTab.updateMethod(
        restOfData.property.request.method as RequestMethodEnum,
      );
      newRequestTab.updateBody(restOfData.property.request.body as Body);
      newRequestTab.updateHeaders(
        restOfData.property.request.headers as KeyValueChecked[],
      );
      newRequestTab.updateTests(restOfData.property.request.tests);
      newRequestTab.updateQueryParams(
        restOfData.property.request.queryParams as KeyValueChecked[],
      );
      newRequestTab.updateAuth(restOfData.property.request.auth as Auth);
      newRequestTab.updateAutoGeneratedHeaders(
        restOfData.property.request.autoGeneratedHeaders as KeyValueChecked[],
      );
      newRequestTab.updateState(
        restOfData.property.request.state as StatePartial,
      );

      const { collectionId, folderId, ...filteredPath } = restOfData.path; // Remove collecitonId and folderId
      newRequestTab.updatePath(filteredPath as TabPath);
      newRequestTab.updateIsSave(false);

      this.tabRepository.createTab(newRequestTab.getValue());
      scrollToTab("");
    }
  };

  private createWebSocketDuplciateTab = async (tabId: string) => {
    const originalTab = await this.tabRepository.getTabById(tabId); // Tab to be copied
    const currWorkSpace =
      await this.workspaceRepository.getActiveWorkspaceDoc();

    if (currWorkSpace) {
      const newWebSocketTab = this.initTab.webSocket(
        "UNTRACKED-" + uuidv4(),
        currWorkSpace._id,
      );
      MixpanelEvent(Events.ADD_NEW_API_REQUEST, { source: "TabBar" });

      // Copy values using setter methods (excluding id, tabId, and timestamp)
      const { id, tabId, timestamp, ...restOfData } =
        originalTab.toMutableJSON();

      newWebSocketTab.updateName(restOfData.name);
      newWebSocketTab.updateDescription(restOfData.description);
      newWebSocketTab.updateUrl(restOfData.property.websocket.url);
      newWebSocketTab.updateHeaders(
        restOfData.property.websocket.headers as KeyValueChecked[],
      );
      newWebSocketTab.updateQueryParams(
        restOfData.property.websocket.queryParams as KeyValueChecked[],
      );
      newWebSocketTab.updateMessage(restOfData.property.websocket.message);
      newWebSocketTab.updateAutoGeneratedHeaders(
        restOfData.property.websocket.autoGeneratedHeaders as KeyValueChecked[],
      );
      newWebSocketTab.updateState(
        restOfData.property.websocket.state as Partial<WebSocketStateType>,
      );

      const { collectionId, folderId, ...filteredPath } = restOfData.path; // Remove collecitonId and folderId
      newWebSocketTab.updatePath(filteredPath as TabPath);
      newWebSocketTab.updateIsSave(false);

      this.tabRepository.createTab(newWebSocketTab.getValue());
      scrollToTab("");
    }
  };

  private createSocketIODuplciateTab = async (tabId: string) => {
    const originalTab = await this.tabRepository.getTabById(tabId); // Tab to be copied
    const currWorkSpace =
      await this.workspaceRepository.getActiveWorkspaceDoc();

    if (currWorkSpace) {
      const newSocketIOTab = this.initTab.socketIo(
        "UNTRACKED-" + uuidv4(),
        currWorkSpace._id,
      );
      MixpanelEvent(Events.ADD_NEW_API_REQUEST, { source: "TabBar" });

      // Copy values using setter methods (excluding id, tabId, and timestamp)
      const { id, tabId, timestamp, ...restOfData } = originalTab._data;

      newSocketIOTab.updateName(restOfData.name);
      newSocketIOTab.updateDescription(restOfData.description);
      newSocketIOTab.updateUrl(restOfData.property.socketio.url);
      newSocketIOTab.updateHeaders(
        restOfData?.property?.socketio?.headers as KeyValueChecked[],
      );
      newSocketIOTab.updateQueryParams(
        restOfData.property.socketio.queryParams as KeyValueChecked[],
      );
      newSocketIOTab.updateEvents(
        restOfData.property.socketio.events as EventsValues[],
      );
      newSocketIOTab.updateEventName(restOfData.property.socketio.eventName);
      newSocketIOTab.updateMessage(restOfData.property.socketio.message);
      newSocketIOTab.updateAutoGeneratedHeaders(
        restOfData.property.socketio.autoGeneratedHeaders as KeyValueChecked[],
      );
      newSocketIOTab.updateState(
        restOfData.property.socketio.state as Partial<SocketIOStateType>,
      );

      const { collectionId, folderId, ...filteredPath } = restOfData.path; // Remove collecitonId and folderId
      newSocketIOTab.updatePath(filteredPath as TabPath);
      newSocketIOTab.updateIsSave(false);

      this.tabRepository.createTab(newSocketIOTab.getValue());
      scrollToTab("");
    }
  };

  private createGraphQLDuplciateTab = async (tabId: string) => {
    const originalTab = await this.tabRepository.getTabById(tabId); // Tab to be copied
    const currWorkSpace =
      await this.workspaceRepository.getActiveWorkspaceDoc();

    if (currWorkSpace) {
      const newGraphQLTab = this.initTab.graphQl(
        "UNTRACKED-" + uuidv4(),
        currWorkSpace._id,
      );
      MixpanelEvent(Events.ADD_NEW_API_REQUEST, { source: "TabBar" });

      // Copy values using setter methods (excluding id, tabId, and timestamp)
      const { id, tabId, timestamp, ...restOfData } =
        originalTab.toMutableJSON();

      newGraphQLTab.updateName(restOfData.name);
      newGraphQLTab.updateDescription(restOfData.description);
      newGraphQLTab.updateUrl(restOfData.property.graphql.url);
      newGraphQLTab.updateHeaders(
        restOfData.property.graphql.headers as KeyValueChecked[],
      );
      newGraphQLTab.updateMutation(restOfData.property.graphql.mutation);
      newGraphQLTab.updateSchema(restOfData.property.graphql.schema);
      newGraphQLTab.updateVariables(restOfData.property.graphql.variables);
      newGraphQLTab.updateAuth(
        restOfData.property.graphql.auth as GraphqlRequestAuthTabInterface,
      );
      newGraphQLTab.updateAutoGeneratedHeaders(
        restOfData.property.graphql
          .autoGeneratedHeaders as GraphqlRequestAutoGeneratedHeadersTabInterface[],
      );
      newGraphQLTab.updateState(
        restOfData.property.graphql
          .state as Partial<GraphqlRequestStateTabInterface>,
      );

      const { collectionId, folderId, ...filteredPath } = restOfData.path; // Remove collecitonId and folderId
      newGraphQLTab.updatePath(filteredPath as TabPath);
      newGraphQLTab.updateIsSave(false);

      this.tabRepository.createTab(newGraphQLTab.getValue());
      scrollToTab("");
    }
  };

  private createAiRequestDuplciateTab = async (tabId: string) => {
    const originalTab = await this.tabRepository.getTabById(tabId); // Tab to be copied
    const currWorkSpace =
      await this.workspaceRepository.getActiveWorkspaceDoc();

    if (currWorkSpace) {
      const newAiRequestTab = this.initTab.aiRequest(
        "UNTRACKED-" + uuidv4(),
        currWorkSpace._id,
      );
      // MixpanelEvent(Events.ADD_NEW_API_REQUEST, { source: "TabBar" });

      // Copy values using setter methods (excluding id, tabId, and timestamp)
      const { id, tabId, timestamp, ...restOfData } =
        originalTab.toMutableJSON();

      newAiRequestTab.updateName(restOfData.name);
      newAiRequestTab.updateDescription(restOfData.description as string);
      newAiRequestTab.updatePath(restOfData.path as TabPath);
      newAiRequestTab.updateAIModelProvider(
        restOfData.property.aiRequest?.aiModelProvider as AiModelProviderEnum,
      );
      newAiRequestTab.updateAIModelVariant(
        restOfData.property.aiRequest?.aiModelVariant as AIModelVariant,
      );
      newAiRequestTab.updateAISystemPrompt(
        restOfData.property.aiRequest?.systemPrompt as string,
      );
      newAiRequestTab.updateAuth(restOfData.property.aiRequest?.auth as Auth);
      newAiRequestTab.updateState({
        ...restOfData.property.aiRequest?.state,
        isChatbotGeneratingResponse: false,
      } as StatePartial);

      const { collectionId, folderId, ...filteredPath } = restOfData.path; // Remove collecitonId and folderId
      newAiRequestTab.updatePath(filteredPath as TabPath);
      newAiRequestTab.updateIsSave(false);

      this.tabRepository.createTab(newAiRequestTab.getValue());
      scrollToTab("");
    }
  };

  public createDuplicateTabByTabId = async (tabId: string) => {
    const originalTab = await this.tabRepository.getTabById(tabId); // Tab to be copied
    const originalTabType = originalTab.toMutableJSON().type as TabTypeEnum;

    switch (originalTabType) {
      case TabTypeEnum.REQUEST:
        return this.createRESTDuplciateTab(tabId);
      case TabTypeEnum.WEB_SOCKET:
        return this.createWebSocketDuplciateTab(tabId);
      case TabTypeEnum.SOCKET_IO:
        return this.createSocketIODuplciateTab(tabId);
      case TabTypeEnum.GRAPHQL:
        return this.createGraphQLDuplciateTab(tabId);
      case TabTypeEnum.AI_REQUEST:
        return this.createAiRequestDuplciateTab(tabId);
      default:
        break;
    }
  };
  // ****** Handling Tab Duplication - Ed ******

  /**
   * Set active tab in store
   * @param id - tab id
   */
  public handleActiveTab = async (id: string) => {
    const selectedTab = await this.tabRepository.activeTab(id);
    const selectedTabJSON = selectedTab?.toMutableJSON();
    await new Sleep().setTime(1000).exec();
    if (selectedTabJSON?.path?.collectionId) {
      addCollectionItem(selectedTabJSON?.path?.collectionId, "collection");
    }
    if (selectedTabJSON?.path?.folderId) {
      addCollectionItem(selectedTabJSON?.path?.folderId, "folder");
    }
    if (selectedTabJSON?.path?.requestId) {
      addCollectionItem(selectedTabJSON?.path?.requestId, "request");
    }
  };

  /**
   * Handle tab drop on tab list
   * @param event
   */
  public onDropEvent = (event: Event) => {
    event.preventDefault();
    this.tabRepository.rearrangeTab(
      this.movedTabStartIndex,
      this.movedTabEndIndex,
    );
  };

  /**
   * Set starting index of tab from tab list
   * @param index - tab index
   */
  public handleDropOnStart = (index: number) => {
    this.movedTabStartIndex = index;
  };

  /**
   * Set ending index of tab in tab list
   * @param index - tab index
   */
  public handleDropOnEnd = (index: number) => {
    this.movedTabEndIndex = index;
  };

  /**
   * Retrieve request inside folder from repository
   * @param collectionId
   * @param folderId
   * @param uuid
   * @returns
   */
  private readRequestInFolder = (
    collectionId: string,
    folderId: string,
    uuid: string,
  ) => {
    return this.collectionRepository.readRequestInFolder(
      collectionId,
      folderId,
      uuid,
    );
  };

  /**
   * Retrieve request or folder from repository
   * @param collectionId
   * @param uuid
   * @returns
   */
  private readRequestOrFolderInCollection = async (
    collectionId: string,
    uuid: string,
  ): Promise<CollectionItemsDto | undefined> => {
    return await this.collectionRepository.readRequestOrFolderInCollection(
      collectionId,
      uuid,
    );
  };

  /**
   * Retrieve collection from repository
   * @param uuid
   * @returns
   */
  public readCollection = async (uuid: string): Promise<CollectionDocument> => {
    return await this.collectionRepository.readCollection(uuid);
  };

  /**
   * Save API Request from unsaved Tab
   * @param componentData - New Tab
   * @param saveDescriptionOnly
   * @returns
   */
  public saveAPIRequest = async (componentData: Tab) => {
    const { folderId, collectionId, workspaceId } = componentData.path;
    if (!workspaceId || !collectionId) {
      return {
        status: "error",
        message: "request is not a part of any workspace or collection",
      };
    }
    const _collection = await this.readCollection(collectionId);
    let userSource = {};
    if (_collection?.activeSync && componentData?.source === "USER") {
      userSource = {
        currentBranch: _collection?.currentBranch,
        source: "USER",
      };
    }
    const _id = componentData.id;

    const requestTabAdapter = new RequestTabAdapter();
    const unadaptedRequest = requestTabAdapter.unadapt(componentData);
    // Save overall api

    const requestMetaData = {
      id: _id,
      name: componentData?.name,
      description: componentData?.description,
      type: ItemType.REQUEST,
    };

    let folderSource;
    let itemSource;
    if (folderId) {
      folderSource = {
        folderId: folderId,
      };
      itemSource = {
        id: folderId,
        type: ItemType.FOLDER,
        items: {
          ...requestMetaData,
          request: unadaptedRequest,
        },
      };
    } else {
      itemSource = {
        ...requestMetaData,
        request: unadaptedRequest,
      };
    }

    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    if (isGuestUser === true) {
      const data = {
        id: requestMetaData.id,
        name: requestMetaData.name,
        description: requestMetaData.description,
        type: "REQUEST",
        request: unadaptedRequest,
        updatedAt: "",
        updatedBy: "Guest User",
      };
      if (!folderId) {
        this.collectionRepository.updateRequestOrFolderInCollection(
          collectionId,
          _id,
          data,
        );
      } else {
        this.collectionRepository.updateRequestInFolder(
          collectionId,
          folderId,
          _id,
          data,
        );
      }
      return true;
    }

    const dt = {
      collectionId: collectionId,
      workspaceId: workspaceId,
      ...folderSource,
      ...userSource,
      items: itemSource as unknown as CollectionItemsDto,
    };
    const res = await updateCollectionRequest(_id, folderId, collectionId, dt);
    if (res.isSuccessful) {
      if (!folderId) {
        this.collectionRepository.updateRequestOrFolderInCollection(
          collectionId,
          _id,
          res.data.data,
        );
      } else {
        this.collectionRepository.updateRequestInFolder(
          collectionId,
          folderId,
          _id,
          res.data.data,
        );
      }
      return true;
    } else {
      return false;
    }
  };

  /**
   * Save Mock API Request from unsaved Tab
   * @param componentData - New Tab
   * @param saveDescriptionOnly
   * @returns
   */
  public saveMockAPIRequest = async (componentData: Tab) => {
    const { folderId, collectionId, workspaceId } = componentData.path;
    if (!workspaceId || !collectionId) {
      return {
        status: "error",
        message: "request is not a part of any workspace or collection",
      };
    }
    const _collection = await this.readCollection(collectionId);
    let userSource = {};
    if (_collection?.activeSync && componentData?.source === "USER") {
      userSource = {
        currentBranch: _collection?.currentBranch,
        source: "USER",
      };
    }
    const _id = componentData.id;

    const requestTabAdapter = new RequestMockTabAdapter();
    const unadaptedRequest = requestTabAdapter.unadapt(componentData);
    // Save overall api

    const requestMetaData = {
      id: _id,
      name: componentData?.name,
      description: componentData?.description,
      type: ItemType.MOCK_REQUEST,
    };

    let folderSource;
    let itemSource;
    if (folderId) {
      folderSource = {
        folderId: folderId,
      };
      itemSource = {
        id: folderId,
        type: ItemType.FOLDER,
        items: {
          ...requestMetaData,
          mockRequest: unadaptedRequest,
        },
      };
    } else {
      itemSource = {
        ...requestMetaData,
        mockRequest: unadaptedRequest,
      };
    }

    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    if (isGuestUser === true) {
      const data = {
        id: requestMetaData.id,
        name: requestMetaData.name,
        description: requestMetaData.description,
        type: "MOCK_REQUEST",
        mockRequest: unadaptedRequest,
        updatedAt: "",
        updatedBy: "Guest User",
      };
      if (!folderId) {
        this.collectionRepository.updateRequestOrFolderInCollection(
          collectionId,
          _id,
          data,
        );
      } else {
        this.collectionRepository.updateRequestInFolder(
          collectionId,
          folderId,
          _id,
          data,
        );
      }
      return true;
    }

    const dt = {
      collectionId: collectionId,
      workspaceId: workspaceId,
      ...folderSource,
      ...userSource,
      items: itemSource,
    };
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const res = await this.collectionService.updateMockRequestInCollection(
      _id,
      dt,
      baseUrl,
    );
    if (res.isSuccessful) {
      if (!folderId) {
        this.collectionRepository.updateRequestOrFolderInCollection(
          collectionId,
          _id,
          res.data.data,
        );
      } else {
        this.collectionRepository.updateRequestInFolder(
          collectionId,
          folderId,
          _id,
          res.data.data,
        );
      }
      return true;
    } else {
      return false;
    }
  };

  /**
   * Save AI Request from unsaved Tab
   * @param componentData - New Tab
   * @param saveDescriptionOnly
   * @returns
   */
  public saveAiRequest = async (componentData: Tab) => {
    const { folderId, collectionId, workspaceId } = componentData.path;
    if (!workspaceId || !collectionId) {
      return {
        status: "error",
        message: "this AI request is not a part of any workspace or collection",
      };
    }
    const _collection = await this.readCollection(collectionId);
    let userSource = {};
    if (_collection?.activeSync && componentData?.source === "USER") {
      userSource = {
        currentBranch: _collection?.currentBranch,
        source: "USER",
      };
    }
    const _id = componentData.id;

    const aiRequestTabAdapter = new AiRequestTabAdapter();
    const unadaptedAIRequest = aiRequestTabAdapter.unadapt(componentData);

    // Save overall api
    const requestMetaData = {
      id: _id,
      name: componentData?.name,
      description: componentData?.description,
      type: ItemType.AI_REQUEST,
    };

    let folderSource;
    let itemSource;
    if (folderId) {
      folderSource = {
        folderId: folderId,
      };
      itemSource = {
        id: folderId,
        type: ItemType.FOLDER,
        items: {
          ...requestMetaData,
          aiRequest: unadaptedAIRequest,
        },
      };
    } else {
      itemSource = {
        ...requestMetaData,
        aiRequest: unadaptedAIRequest,
      };
    }

    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    if (isGuestUser === true) {
      const data = {
        id: requestMetaData.id,
        name: requestMetaData.name,
        description: requestMetaData.description,
        type: "AI_REQUEST",
        mockRequest: unadaptedAIRequest,
        updatedAt: "",
        updatedBy: "Guest User",
      };
      if (!folderId) {
        this.collectionRepository.updateRequestOrFolderInCollection(
          collectionId,
          _id,
          data,
        );
      } else {
        this.collectionRepository.updateRequestInFolder(
          collectionId,
          folderId,
          _id,
          data,
        );
      }
      return true;
    }

    const dt = {
      collectionId: collectionId,
      workspaceId: workspaceId,
      ...folderSource,
      ...userSource,
      items: itemSource,
    };
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const res = await this.collectionService.updateAiRequestInCollection(
      _id,
      dt,
      baseUrl,
    );
    if (res.isSuccessful) {
      if (!folderId) {
        this.collectionRepository.updateRequestOrFolderInCollection(
          collectionId,
          _id,
          res.data.data,
        );
      } else {
        this.collectionRepository.updateRequestInFolder(
          collectionId,
          folderId,
          _id,
          res.data.data,
        );
      }
      return true;
    } else {
      return false;
    }
  };

  /**
   * Handle updating tab
   * @param data :any - tab data i.e. collection, folder or request
   * @param route :string - path to collection, folder or request
   * @param _id :string - if of the tab
   */
  public updateTab = async (_id: string, data: Partial<Tab>) => {
    this.tabRepository.updateTabByMongoId(_id, data);
  };

  /**
   * Handle deleting collection from repository
   * @param workspaceId :string - workspace id in which the collection is saved
   * @param collectionId :string - collection id to be deleted
   * @returns :void
   */
  private deleteCollectioninWorkspace = (
    workspaceId: string,
    collectionId: string,
  ) => {
    return this.workspaceRepository.deleteCollectionInWorkspace(
      workspaceId,
      collectionId,
    );
  };

  /**
   * Removes tabs from workspace
   * @param mainEntityId - tab Ids to be deleted
   * @param workspaceId - ID of the workspace containing the tabs
   * @returns Promise<void>
   */
  private removeMultipleTabs = async (ids: string[], workspaceId: string) => {
    if (!ids.length) return;
    await this.tabRepository.deleteTabsWithTabIdInAWorkspace(workspaceId, ids);
  };

  /**
   * Removes a primary tab and all its associated child tabs from the workspace
   * @param mainEntityId - ID of the main entity (request, collection, folder, etc.)
   * @param workspaceId - ID of the workspace containing the tabs
   * @param entityType - Type of the entity ('request', 'collection', 'folder')
   * @returns Promise<void>
   */
  private async removeTabWithChildren(
    mainEntityId: string,
    workspaceId: string,
    entityType: "request" | "collection" | "folder",
  ): Promise<void> {
    const tabsIdsToDelete = [];
    let childTabs = [];

    // Remove the main tab
    const mainTabId = await this.tabRepository.getTabById(mainEntityId);
    if (mainTabId) tabsIdsToDelete.push(mainTabId.tabId);

    // Get child tabs based on entity type
    if (entityType === "request") {
      childTabs = await this.tabRepository.getTabsByRequestId(mainEntityId);
    } else if (entityType === "collection") {
      childTabs = await this.tabRepository.getTabsByCollectionId(mainEntityId);
    } else if (entityType === "folder") {
      childTabs = await this.tabRepository.getTabsByFolderId(mainEntityId);
    }

    // Delete all child tabs if any exist
    if (childTabs.length > 0) {
      const allChildTabs = childTabs.map((tab) => tab.tabId);
      tabsIdsToDelete.push(...allChildTabs);
    }
    await this.removeMultipleTabs(tabsIdsToDelete, workspaceId);
  }

  /**
   * Get list of collections from current active workspace
   * @returns :Observable<CollectionDocument[]> - the list of collection from current active workspace
   */
  public getCollectionList = () => {
    return this.collectionRepository.getCollection();
  };

  /**
   * Get the active workspace
   * @returns :Observable<WorkspaceDocument> - the active workspace
   */
  public getActiveWorkspace = (): Observable<WorkspaceDocument> => {
    return this.workspaceRepository.getActiveWorkspace();
  };

  /**
   * Adds collection to the repository
   * @param collection :CollectionDocument - the collection to be added
   */
  private addCollection = (collection: CollectionDto) => {
    this.collectionRepository.addCollection(collection);
  };

  /**
   * @description - refreshes github respository data
   */
  public fetchGithubRepo = async () => {
    const githubRepoId = "sparrow-github";
    const response = await this.githubService.getRepoMetaData(
      "sparrowapp-dev/sparrow-app",
    );
    if (response.isSuccessful) {
      const githubDocument = await this.githhubRepoRepository.findOne({
        id: githubRepoId,
      });
      if (!githubDocument) {
        await this.githhubRepoRepository.insert({
          id: githubRepoId,
          stargazers_count: response.data.stargazers_count,
        });
      } else {
        await this.githhubRepoRepository.update(
          {
            id: githubRepoId,
          },
          {
            stargazers_count: response.data.stargazers_count,
          },
        );
      }
      return response.data;
    }
  };
  /**
   * Generate available name of new collection like New collection 2 if New collection is already taken
   * @param list - list of collections
   * @param name  - name to be chacked
   * @returns - new unique name
   */
  private getNextCollection = (list: CollectionDocType[], name: string) => {
    const isNameAvailable: (proposedName: string) => boolean = (
      proposedName,
    ) => {
      return list.some((element: CollectionDocType) => {
        return element.name === proposedName;
      });
    };

    if (!isNameAvailable(name)) {
      return name;
    }

    for (let i = 2; i < list.length + 10; i++) {
      const proposedName: string = `${name} ${i}`;
      if (!isNameAvailable(proposedName)) {
        return proposedName;
      }
    }

    return null;
  };

  /**
   * Update tabs after moving a request
   */
  private updateTabsAfterMove = async (
    collectionId: string,
    folderId: string,
    requestId: string,
  ): Promise<void> => {
    const tabsToUpdate = await this.tabRepository.getTabsByRequestId(requestId);
    for (const tab of tabsToUpdate) {
      await this.tabRepository.updateTabByMongoId(tab.id, {
        collectionId,
        folderId,
      });
    }
  };

  /**
   * Handle moving request for guest users (local only)
   */
  private handleGuestUserMove = async (
    oldCollectionId: string,
    newCollectionId: string,
    oldFolderId: string,
    newFolderId: string,
    requestId: string,
    targetRequestId?: string,
    insertPosition?: "before" | "after",
  ): Promise<void> => {
    const oldCollection = await this.readCollection(oldCollectionId);
    const workspaceId = oldCollection?.workspaceId;

    if (!workspaceId) {
      throw new Error("Workspace not found");
    }

    let newCollection = oldCollection;

    if (newCollectionId !== oldCollectionId) {
      newCollection = await this.readCollection(newCollectionId);
    }
    let targetName = newCollection?.name || "collection";

    if (newFolderId) {
      const folderDetails = await this.readRequestOrFolderInCollection(
        newCollectionId,
        newFolderId,
      );
      targetName = folderDetails?.name || "folder";
    }
    // Move the request using the repository method
    await this.collectionRepository.moveRequest(
      oldCollectionId,
      newCollectionId,
      oldFolderId,
      newFolderId,
      requestId,
      targetRequestId,
      insertPosition,
    );

    await this.updateTabsAfterMove(newCollectionId, newFolderId, requestId);

    // Dynamic notification based on whether moved to folder or collection root
    const notificationMessage = newFolderId
      ? `Request moved to folder "${targetName}"`
      : `Request moved to collection "${targetName}"`;
    notifications.success(notificationMessage);
  };

  /**
   * Handle moving request for logged-in users (API + local)
   */
  private handleLoggedInUserMove = async (
    oldCollectionId: string,
    newCollectionId: string,
    oldFolderId: string,
    newFolderId: string,
    requestId: string,
    targetRequestId?: string,
    insertPosition?: "before" | "after",
  ): Promise<void> => {
    const oldCollection = await this.readCollection(oldCollectionId);
    const workspaceId = oldCollection?.workspaceId;

    if (!workspaceId) {
      throw new Error("Workspace not found");
    }

    let newCollection = oldCollection;

    if (newCollectionId !== oldCollectionId) {
      newCollection = await this.readCollection(newCollectionId);
    }
    let targetName = newCollection?.name || "collection";

    if (newFolderId) {
      const folderDetails = await this.readRequestOrFolderInCollection(
        newCollectionId,
        newFolderId,
      );
      targetName = folderDetails?.name || "folder";
    }

    const baseUrl = await this.constructBaseUrl(workspaceId);

    const response = await this.collectionService.moveRequest(
      oldCollectionId,
      newCollectionId,
      oldFolderId,
      newFolderId,
      requestId,
      workspaceId,
      baseUrl,
      targetRequestId,
      insertPosition,
    );
    if (response.isSuccessful) {
      await this.collectionRepository.moveRequest(
        oldCollectionId,
        newCollectionId,
        oldFolderId,
        newFolderId,
        requestId,
        targetRequestId,
        insertPosition,
      );
      await this.updateTabsAfterMove(oldCollectionId, newFolderId, requestId);

      const notificationMessage = newFolderId
        ? `Request moved to folder "${targetName}"`
        : `Request moved to collection "${targetName}"`;
      notifications.success(notificationMessage);
    }
  };

  public handleMoveRequest = async (
    oldCollectionId: string,
    newCollectionId: string,
    oldFolderId: string,
    newFolderId: string,
    requestId: string,
    targetRequestId?: string,
    insertPosition?: "before" | "after",
  ) => {
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    try {
      if (isGuestUser === true) {
        await this.handleGuestUserMove(
          oldCollectionId,
          newCollectionId,
          oldFolderId,
          newFolderId,
          requestId,
          targetRequestId,
          insertPosition,
        );
      } else {
        await this.handleLoggedInUserMove(
          oldCollectionId,
          newCollectionId,
          oldFolderId,
          newFolderId,
          requestId,
          targetRequestId,
          insertPosition,
        );
      }
    } catch (error) {
      console.error("Error in handleMoveRequest:", error);
      throw error;
    }
  };

  /**
   * Handle create empty collection
   * @param workspaceId :string
   */
  public handleCreateCollection = async (workspaceId: string) => {
    const collectionsRx =
      await this.collectionRepository.getCollectionsByWorkspaceId(workspaceId);
    const collectionsDoc = collectionsRx.map((collection) =>
      collection.toMutableJSON(),
    );
    const newCollection = {
      id: UntrackedItems.UNTRACKED + uuidv4(),
      name: this.getNextCollection(collectionsDoc, "New Collection") as string,
      items: [],
      createdAt: new Date().toISOString(),
    };
    let response;
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    if (isGuestUser !== true) {
      const baseUrl = await this.constructBaseUrl(workspaceId);
      response = await this.collectionService.addCollection(
        {
          name: newCollection.name,
          workspaceId: workspaceId,
          description: "",
        },
        baseUrl,
      );

      if (response.isSuccessful && response.data.data) {
        const res = response.data.data;
        await this.collectionRepository.addCollection({
          ...res,
          id: res._id,
          workspaceId: workspaceId,
          description: "",
        });
        const adaptCollection = new CollectionTabAdapter().adapt(workspaceId, {
          ...response.data.data,
          id: response.data.data._id,
        });
        this.tabRepository.createTab(adaptCollection);
        scrollToTab("");

        addCollectionItem(response.data.data._id, "collection");

        await this.workspaceRepository.updateCollectionInWorkspace(
          workspaceId,
          {
            id: response.data.data._id,
            name: newCollection.name,
          },
        );
        notifications.success("New Collection created successfully.");
        MixpanelEvent(Events.CREATE_COLLECTION, {
          source: "USER",
          collectionName: response.data.data.name,
          collectionId: response.data.data._id,
        });
      } else {
        notifications.error(response.message ?? "Failed to create collection!");
      }
    } else {
      const collectionId = uuidv4();
      const dt = {
        id: collectionId,
        name: newCollection.name,
        workspaceId: workspaceId,
        items: [],
        description: "",
        createdAt: newCollection.createdAt,
        createdBy: "guestUser",
        totalRequests: 0,
        updatedAt: newCollection.createdAt,
        updatedBy: "guestUser",
      };
      await this.collectionRepository.addCollection(dt);
      const adaptCollection = new CollectionTabAdapter().adapt(workspaceId, dt);
      this.tabRepository.createTab(adaptCollection);
      scrollToTab("");

      addCollectionItem(dt.id, "collection");
      await this.workspaceRepository.updateCollectionInWorkspace(workspaceId, {
        id: dt.id,
        name: dt.name,
      });
      notifications.success("New Collection created successfully.");
    }
    return response;
  };

  /**
   * Handle create empty mock collection
   * @param workspaceId :string
   */
  public handleCreateMockCollection = async (workspaceId: string) => {
    const collectionsRx =
      await this.collectionRepository.getCollectionsByWorkspaceId(workspaceId);
    const collectionsDoc = collectionsRx.map((collection) =>
      collection.toMutableJSON(),
    );
    const newCollection = {
      id: UntrackedItems.UNTRACKED + uuidv4(),
      name: this.getNextCollection(
        collectionsDoc,
        "New Mock Collection",
      ) as string,
      items: [],
      createdAt: new Date().toISOString(),
    };
    let response;
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    if (isGuestUser !== true) {
      const baseUrl = await this.constructBaseUrl(workspaceId);
      response = await this.collectionService.addCollection(
        {
          name: newCollection.name,
          collectionType: CollectionTypeBaseEnum.MOCK,
          workspaceId: workspaceId,
          description: "",
        },
        baseUrl,
      );

      if (response.isSuccessful && response.data.data) {
        const res = response.data.data;
        await this.collectionRepository.addCollection({
          ...res,
          id: res._id,
          workspaceId: workspaceId,
          description: "",
          collectionType: CollectionTypeBaseEnum.MOCK,
        });
        const adaptCollection = new CollectionTabAdapter().adapt(workspaceId, {
          ...response.data.data,
          id: response.data.data._id,
        });
        this.tabRepository.createTab(adaptCollection);
        scrollToTab("");

        await this.workspaceRepository.updateCollectionInWorkspace(
          workspaceId,
          {
            id: response.data.data._id,
            name: newCollection.name,
          },
        );
        notifications.success(
          `'${newCollection.name}' mock collection created successfully.`,
        );
        MixpanelEvent(Events.CREATE_COLLECTION, {
          source: "USER",
          collectionName: response.data.data.name,
          collectionId: response.data.data._id,
        });
      } else {
        notifications.error(
          response.message ??
            "Failed to create mock collection. Please try again.",
        );
      }
    } else {
      const collectionId = uuidv4();
      const dt = {
        id: collectionId,
        name: newCollection.name,
        workspaceId: workspaceId,
        collectionType: CollectionTypeBaseEnum.MOCK,
        items: [],
        description: "",
        createdAt: newCollection.createdAt,
        createdBy: "guestUser",
        totalRequests: 0,
        updatedAt: newCollection.createdAt,
        updatedBy: "guestUser",
      };
      await this.collectionRepository.addCollection(dt);
      const adaptCollection = new CollectionTabAdapter().adapt(workspaceId, dt);
      this.tabRepository.createTab(adaptCollection);
      scrollToTab("");

      await this.workspaceRepository.updateCollectionInWorkspace(workspaceId, {
        id: dt.id,
        name: dt.name,
      });
      notifications.success(
        `'${newCollection.name}' mock collection created successfully.`,
      );
    }
    return response;
  };

  /**
   * Handle Import Api using Curl
   * @param parsedCurlData: TransformedRequest - Curl JSON
   */
  private handleImportCurl = async (
    workspaceId: string,
    parsedCurlData: TransformedRequest | undefined,
  ) => {
    if (parsedCurlData) {
      const requestTabAdapter = new RequestTabAdapter();
      const tabId = UntrackedItems.UNTRACKED + uuidv4();
      const adaptedRequest = requestTabAdapter.adapt(
        workspaceId || "",
        "",
        "",
        {
          ...parsedCurlData,
          id: tabId,
        },
      );
      adaptedRequest.isSaved = false;
      await this.tabRepository.createTab(adaptedRequest);
      scrollToTab("");

      notifications.success("cURL imported successfully.");
    } else {
      notifications.error("Failed to import cURL. Please try again.");
    }
    MixpanelEvent(Events.IMPORT_API_VIA_CURL, {
      source: "curl import popup",
    });
  };

  /**
   * Handles creating unique name for new collection, folder or request
   * @param list :any[] - list of collection, folder or request
   * @param type :string - type of element of list, i.e. collection, folder, request
   * @param name :string - name of new element
   * @returns :string - new proposed name of new collection, folder or request
   */
  private getNextName = (
    list: { type: string; name: string }[],
    type: string,
    name: string,
  ) => {
    const isNameAvailable: (proposedName: string) => boolean = (
      proposedName,
    ) => {
      return list.some((element) => {
        return element.type === type && element.name === proposedName;
      });
    };

    if (!isNameAvailable(name)) {
      return name;
    }

    for (let i = 2; i < list.length + 10; i++) {
      const proposedName: string = `${name} ${i}`;
      if (!isNameAvailable(proposedName)) {
        return proposedName;
      }
    }
  };

  /**
   * Handle creating a new request in a collection
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection in which new request is going to be created
   * @returns :void
   */
  private handleCreateRequestInCollection = async (
    workspaceId: string,
    collection: CollectionDto,
  ) => {
    const request = new InitRequestTab(
      UntrackedItems.UNTRACKED + uuidv4(),
      workspaceId,
    );
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    let userSource = {};
    if (collection?.activeSync) {
      userSource = {
        currentBranch: collection?.currentBranch
          ? collection?.currentBranch
          : collection?.primaryBranch,
        source: "USER",
      };
    }
    const requestObj = {
      collectionId: collection.id,
      workspaceId: workspaceId,
      ...userSource,
      items: {
        name: request.getValue().name,
        type: request.getValue().type,
        description: "",
        request: {
          method: request?.getValue().property?.request?.method,
        } as RequestDto,
        ...(isGuestUser ? { updatedAt: new Date().toISOString() } : {}),
      },
    };
    await this.collectionRepository.addRequestOrFolderInCollection(
      collection.id,
      {
        ...requestObj.items,
        id: request.getValue().id,
      },
    );

    if (isGuestUser === true) {
      const res =
        await this.collectionRepository.readRequestOrFolderInCollection(
          requestObj.collectionId,
          request.getValue().id,
        );
      if (res) {
        res.id = uuidv4();
      }
      await this.collectionRepository.updateRequestOrFolderInCollection(
        collection.id,
        request.getValue().id,
        res,
      );

      request.updateId(res?.id as string);
      request.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: "",
      });
      request.updateIsSave(true);
      await this.tabRepository.createTab(request.getValue());
      scrollToTab("");
      MixpanelEvent(Events.CREATE_REQUEST, {
        source: "Collection list",
      });
      return;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response = await this.collectionService.addRequestInCollection(
      requestObj,
      baseUrl,
    );
    if (response.isSuccessful && response.data.data) {
      const res = response.data.data;

      this.collectionRepository.updateRequestOrFolderInCollection(
        collection.id,
        request.getValue().id,
        res,
      );

      // request.id = res.id;
      // request.path.workspaceId = workspaceId;
      // request.path.collectionId = collection.id;
      // request.property.request.save.api = true;
      // request.property.request.save.description = true;
      request.updateId(res.id);
      request.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: "",
      });
      request.updateIsSave(true);
      // this.handleOpenRequest(
      //   workspaceId,
      //   collection,
      //   {
      //     id: "",
      //     name: "",
      //   },
      //   request,
      // );
      this.tabRepository.createTab(request.getValue());
      scrollToTab("");
      MixpanelEvent(Events.CREATE_REQUEST, {
        source: "Collection list",
      });
      return;
    } else {
      this.collectionRepository.deleteRequestOrFolderInCollection(
        collection.id,
        request.getValue().id,
      );
      notifications.error(response.message);
    }
  };

  /**
   * Handle creating a new mock request in a collection
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection in which new request is going to be created
   * @returns :void
   */
  private handleCreateMockRequestInCollection = async (
    workspaceId: string,
    collection: CollectionDto,
  ) => {
    const mockRequest = new InitMockRequestTab(
      UntrackedItems.UNTRACKED + uuidv4(),
      workspaceId,
    );
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    let userSource = {};
    if (collection?.activeSync) {
      userSource = {
        currentBranch: collection?.currentBranch
          ? collection?.currentBranch
          : collection?.primaryBranch,
        source: "USER",
      };
    }
    const requestObj = {
      collectionId: collection.id,
      workspaceId: workspaceId,
      ...userSource,
      items: {
        name: mockRequest.getValue().name,
        type: CollectionItemTypeBaseEnum.MOCK_REQUEST,
        description: "",
        mockRequest: {
          method: mockRequest?.getValue().property?.mockRequest?.method,
          url: "",
        },
        ...(isGuestUser ? { updatedAt: new Date().toISOString() } : {}),
      },
    };
    await this.collectionRepository.addRequestOrFolderInCollection(
      collection.id,
      {
        ...requestObj.items,
        id: mockRequest.getValue().id,
      },
    );

    if (isGuestUser === true) {
      const res =
        await this.collectionRepository.readRequestOrFolderInCollection(
          requestObj.collectionId,
          mockRequest.getValue().id,
        );
      if (res) {
        res.id = uuidv4();
      }
      await this.collectionRepository.updateRequestOrFolderInCollection(
        collection.id,
        mockRequest.getValue().id,
        res,
      );

      mockRequest.updateId(res?.id as string);
      mockRequest.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: "",
      });
      mockRequest.updateIsSave(true);
      await this.tabRepository.createTab(mockRequest.getValue());
      scrollToTab("");
      // MixpanelEvent(Events.CREATE_REQUEST, {
      //   source: "Collection list",
      // });
      return;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response = await this.collectionService.addMockRequestInCollection(
      requestObj,
      baseUrl,
    );
    if (response.isSuccessful && response.data.data) {
      const res = response.data.data;

      this.collectionRepository.updateRequestOrFolderInCollection(
        collection.id,
        mockRequest.getValue().id,
        res,
      );

      // request.id = res.id;
      // request.path.workspaceId = workspaceId;
      // request.path.collectionId = collection.id;
      // request.property.request.save.api = true;
      // request.property.request.save.description = true;
      mockRequest.updateId(res.id);
      mockRequest.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: "",
      });
      // mockRequest.updateUrl(collection?.mockCollectionUrl);
      mockRequest.updateIsSave(true);
      if ((collection.collectionType = CollectionTypeBaseEnum.MOCK)) {
        mockRequest.updateLabel(CollectionTypeBaseEnum.MOCK);
      }
      // this.handleOpenRequest(
      //   workspaceId,
      //   collection,
      //   {
      //     id: "",
      //     name: "",
      //   },
      //   request,
      // );
      this.tabRepository.createTab(mockRequest.getValue());
      scrollToTab("");
      // MixpanelEvent(Events.CREATE_REQUEST, {
      //   source: "Collection list",
      // });
      return;
    } else {
      this.collectionRepository.deleteRequestOrFolderInCollection(
        collection.id,
        mockRequest.getValue().id,
      );
      notifications.error(response.message);
    }
  };

  /**
   * Handle creating a new AI request in a collection
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection in which new request is going to be created
   * @returns :void
   */
  private handleCreateAiRequestInCollection = async (
    workspaceId: string,
    collection: CollectionDto,
  ) => {
    const aiRequest = new InitAiRequestTab(
      UntrackedItems.UNTRACKED + uuidv4(),
      workspaceId,
    );
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    let userSource = {};
    if (collection?.activeSync) {
      userSource = {
        currentBranch: collection?.currentBranch
          ? collection?.currentBranch
          : collection?.primaryBranch,
        source: "USER",
      };
    }
    const aiRequestObj = {
      collectionId: collection.id,
      workspaceId: workspaceId,
      ...userSource,
      items: {
        name: aiRequest.getValue().name,
        type: aiRequest.getValue().type,
        description: "",
        aiRequest: {
          aiModelProvider:
            aiRequest?.getValue().property?.aiRequest?.aiModelProvider,
          aiModelVariant:
            aiRequest?.getValue().property?.aiRequest?.aiModelVariant,
        } as AiRequestBaseInterface,
        ...(isGuestUser ? { updatedAt: new Date().toISOString() } : {}),
      },
    };

    await this.collectionRepository.addRequestOrFolderInCollection(
      collection.id,
      {
        ...aiRequestObj.items,
        id: aiRequest.getValue().id,
      },
    );

    if (isGuestUser === true) {
      const res =
        await this.collectionRepository.readRequestOrFolderInCollection(
          aiRequestObj.collectionId,
          aiRequest.getValue().id,
        );
      if (res) {
        res.id = uuidv4();
      }
      await this.collectionRepository.updateRequestOrFolderInCollection(
        collection.id,
        aiRequest.getValue().id,
        res,
      );

      aiRequest.updateId(res?.id as string);
      aiRequest.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: "",
      });
      aiRequest.updateIsSave(true);
      await this.tabRepository.createTab(aiRequest.getValue());
      scrollToTab("");
      // MixpanelEvent(Events.CREATE_REQUEST, {
      //   source: "Collection list",
      // });
      return;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response = await this.collectionService.addAiRequestInCollection(
      aiRequestObj,
      baseUrl,
    );
    if (response.isSuccessful && response.data.data) {
      const res = response.data.data;

      this.collectionRepository.updateRequestOrFolderInCollection(
        collection.id,
        aiRequest.getValue().id,
        res,
      );

      aiRequest.updateId(res.id);
      aiRequest.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: "",
      });
      aiRequest.updateIsSave(true);

      this.tabRepository.createTab(aiRequest.getValue());
      scrollToTab("");
      // MixpanelEvent(Events.CREATE_REQUEST, {
      //   source: "Collection list",
      // });
      return;
    } else {
      this.collectionRepository.deleteRequestOrFolderInCollection(
        collection.id,
        aiRequest.getValue().id,
      );
      notifications.error(response.message);
    }
  };

  /**
   * Handle creating a new web socket in a collection
   * @param workspaceId
   * @param collection - the collection in which new web socket is going to be created
   */
  private handleCreateWebSocketInCollection = async (
    workspaceId: string,
    collection: CollectionDto,
  ) => {
    const websocket = new InitWebSocketTab(
      UntrackedItems.UNTRACKED + uuidv4(),
      workspaceId,
    );
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    let userSource = {};
    if (collection?.activeSync) {
      userSource = {
        currentBranch: collection?.currentBranch
          ? collection?.currentBranch
          : collection?.primaryBranch,
        source: "USER",
      };
    }
    const websocketObj = {
      collectionId: collection.id,
      workspaceId: workspaceId,
      ...userSource,
      items: {
        name: websocket.getValue().name,
        type: websocket.getValue().type,
        description: "",
        websocket: {},
        ...(isGuestUser ? { updatedAt: new Date().toISOString() } : {}),
      },
    };
    await this.collectionRepository.addRequestOrFolderInCollection(
      collection.id as string,
      {
        ...websocketObj.items,
        id: websocket.getValue().id,
      },
    );

    if (isGuestUser === true) {
      const res =
        await this.collectionRepository.readRequestOrFolderInCollection(
          websocketObj.collectionId as string,
          websocket.getValue().id,
        );
      if (res) {
        res.id = uuidv4();
      }
      await this.collectionRepository.updateRequestOrFolderInCollection(
        collection.id as string,
        websocket.getValue().id,
        res,
      );

      websocket.updateId(res?.id as string);
      websocket.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: "",
      });
      websocket.updateIsSave(true);
      await this.tabRepository.createTab(websocket.getValue());
      scrollToTab("");
      MixpanelEvent(Events.CREATE_REQUEST, {
        source: "Collection list",
      });
      return;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response = await this.collectionService.addSocketInCollection(
      websocketObj,
      baseUrl,
    );
    if (response.isSuccessful && response.data.data) {
      const res = response.data.data;

      this.collectionRepository.updateRequestOrFolderInCollection(
        collection.id as string,
        websocket.getValue().id,
        res,
      );

      websocket.updateId(res.id);
      websocket.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: "",
      });
      websocket.updateIsSave(true);

      this.tabRepository.createTab(websocket.getValue());
      scrollToTab("");
      MixpanelEvent(Events.CREATE_REQUEST, {
        source: "Collection list",
      });
      return;
    } else {
      this.collectionRepository.deleteRequestOrFolderInCollection(
        collection.id,
        websocket.getValue().id,
      );
      notifications.error(response.message);
    }
  };

  /**
   * Handle creating a new socket io in a collection
   * @param _workspaceId - workspace id
   * @param _collection - the collection in which new socket io is going to be created
   */
  private handleCreateSocketIoInCollection = async (
    _workspaceId: string,
    _collection: CollectionDto,
  ) => {
    const socketIoTab = new InitTab().socketIo(uuidv4(), _workspaceId);
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    const socketIoOfCollectionPayload: SocketIORequestCreateUpdateInCollectionPayloadDtoInterface =
      {
        collectionId: _collection.id,
        workspaceId: _workspaceId,
        currentBranch: _collection.activeSync
          ? _collection.currentBranch
          : undefined,
        source: _collection.activeSync ? "USER" : undefined,
        items: {
          name: socketIoTab.getValue().name,
          type: CollectionItemTypeBaseEnum.SOCKETIO,
          description: "",
          socketio: {},
          ...(isGuestUser ? { updatedAt: new Date().toISOString() } : {}),
        },
      };

    if (isGuestUser === true) {
      await this.collectionRepository.addRequestOrFolderInCollection(
        _collection.id as string,
        {
          ...socketIoOfCollectionPayload.items,
          id: socketIoTab.getValue().id,
        },
      );
      socketIoTab.updatePath({
        workspaceId: _workspaceId,
        collectionId: _collection.id,
        folderId: "",
      });
      socketIoTab.updateIsSave(true);
      await this.tabRepository.createTab(socketIoTab.getValue());
      scrollToTab("");
      MixpanelEvent(Events.CREATE_REQUEST, {
        source: "Collection list",
      });
      return;
    }

    const baseUrl = await this.constructBaseUrl(_workspaceId);
    const response = await this.collectionService.addSocketIoInCollection(
      socketIoOfCollectionPayload,
      baseUrl,
    );
    if (response.isSuccessful && response.data.data) {
      const res = response.data.data;

      await this.collectionRepository.addRequestOrFolderInCollection(
        _collection.id as string,
        {
          ...res,
        },
      );

      socketIoTab.updateId(res.id as string);
      socketIoTab.updatePath({
        workspaceId: _workspaceId,
        collectionId: _collection.id,
        folderId: "",
      });
      socketIoTab.updateIsSave(true);

      this.tabRepository.createTab(socketIoTab.getValue());
      scrollToTab("");
      MixpanelEvent(Events.CREATE_REQUEST, {
        source: "Collection list",
      });
      return;
    } else {
      this.collectionRepository.deleteRequestOrFolderInCollection(
        _collection.id,
        socketIoTab.getValue().id,
      );
      notifications.error(response.message);
    }
  };

  /**
   * Handle creating a new graphql in a collection
   * @param _workspaceId - workspace id
   * @param _collection - the collection in which new graphql is going to be created
   */
  private handleCreateGraphqlInCollection = async (
    _workspaceId: string,
    _collection: CollectionDto,
  ) => {
    const graphqlTab = new InitTab().graphQl(uuidv4(), _workspaceId);
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    const graphqlOfCollectionPayload: GraphqlRequestCreateUpdateInCollectionPayloadDtoInterface =
      {
        collectionId: _collection.id,
        workspaceId: _workspaceId,
        currentBranch: _collection.activeSync
          ? _collection.currentBranch
          : undefined,
        source: _collection.activeSync ? "USER" : undefined,
        items: {
          name: graphqlTab.getValue().name,
          type: CollectionItemTypeBaseEnum.GRAPHQL,
          description: "",
          graphql: {},
          ...(isGuestUser ? { updatedAt: new Date().toISOString() } : {}),
        },
      };

    if (isGuestUser === true) {
      await this.collectionRepository.addRequestOrFolderInCollection(
        _collection.id as string,
        {
          ...graphqlOfCollectionPayload.items,
          id: graphqlTab.getValue().id,
        },
      );
      graphqlTab.updatePath({
        workspaceId: _workspaceId,
        collectionId: _collection.id,
        folderId: "",
      });
      graphqlTab.updateIsSave(true);
      await this.tabRepository.createTab(graphqlTab.getValue());
      scrollToTab("");
      return;
    }

    const baseUrl = await this.constructBaseUrl(_workspaceId);
    const response = await this.collectionService.addGraphqlInCollection(
      graphqlOfCollectionPayload,
      baseUrl,
    );
    if (response.isSuccessful && response.data.data) {
      const res = response.data.data;

      await this.collectionRepository.addRequestOrFolderInCollection(
        _collection.id as string,
        {
          ...res,
        },
      );

      graphqlTab.updateId(res.id as string);
      graphqlTab.updatePath({
        workspaceId: _workspaceId,
        collectionId: _collection.id,
        folderId: "",
      });
      graphqlTab.updateIsSave(true);

      this.tabRepository.createTab(graphqlTab.getValue());
      scrollToTab("");

      return;
    } else {
      this.collectionRepository.deleteRequestOrFolderInCollection(
        _collection.id,
        graphqlTab.getValue().id,
      );
      notifications.error(response.message);
    }
  };

  /**
   * Handles creating a new request in a folder
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection in which new request is going to be created
   * @param explorer : - the folder in which new request is going to be created
   * @returns :void
   */
  private handleCreateRequestInFolder = async (
    workspaceId: string,
    collection: CollectionDto,
    explorer: CollectionItemsDto,
  ) => {
    const sampleRequest = new InitRequestTab(
      UntrackedItems.UNTRACKED + uuidv4(),
      workspaceId,
    );
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    let userSource = {};
    if (collection.activeSync && explorer?.source === "USER") {
      userSource = {
        currentBranch: collection.currentBranch
          ? collection.currentBranch
          : collection.primaryBranch,
        source: "USER",
      };
    }
    const requestObj = {
      collectionId: collection.id,
      workspaceId: workspaceId,
      ...userSource,
      folderId: explorer.id,
      items: {
        name: explorer.name,
        type: ItemType.FOLDER,
        id: explorer.id,
        items: {
          name: sampleRequest.getValue().name,
          type: sampleRequest.getValue().type,
          description: "",
          request: {
            method: sampleRequest.getValue().property.request?.method,
          } as RequestDto,
          ...(isGuestUser ? { updatedAt: new Date().toISOString() } : {}),
        },
      },
    };

    await this.collectionRepository.addRequestInFolder(
      requestObj.collectionId,
      requestObj.folderId,
      {
        ...requestObj.items.items,
        id: sampleRequest.getValue().id,
      },
    );

    if (isGuestUser === true) {
      const res = (await this.collectionRepository.readRequestInFolder(
        requestObj.collectionId,
        requestObj.folderId,
        sampleRequest.getValue().id,
      )) as CollectionItemsDto;
      res.id = uuidv4();
      this.collectionRepository.updateRequestInFolder(
        requestObj.collectionId,
        requestObj.folderId,
        sampleRequest.getValue().id,
        res,
      );

      sampleRequest.updateId(res.id);
      sampleRequest.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: explorer.id,
      });
      sampleRequest.updateIsSave(true);
      this.tabRepository.createTab(sampleRequest.getValue());

      scrollToTab("");
      MixpanelEvent(Events.CREATE_REQUEST, {
        source: "Collection list",
      });
      return;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response = await this.collectionService.addRequestInCollection(
      requestObj,
      baseUrl,
    );
    if (response.isSuccessful && response.data.data) {
      const request = response.data.data;

      this.collectionRepository.updateRequestInFolder(
        requestObj.collectionId,
        requestObj.folderId,
        sampleRequest.getValue().id,
        request,
      );

      sampleRequest.updateId(request.id);
      sampleRequest.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: explorer.id,
      });
      sampleRequest.updateIsSave(true);
      this.tabRepository.createTab(sampleRequest.getValue());

      scrollToTab("");
      MixpanelEvent(Events.CREATE_REQUEST, {
        source: "Collection list",
      });
      return;
    } else {
      this.collectionRepository.deleteRequestInFolder(
        requestObj.collectionId,
        requestObj.folderId,
        sampleRequest.getValue().id,
      );
    }
  };

  /**
   * Handles creating a new mock request in a folder
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection in which new mock request is going to be created
   * @param explorer : - the folder in which new mock request is going to be created
   * @returns :void
   */
  private handleCreateMockRequestInFolder = async (
    workspaceId: string,
    collection: CollectionDto,
    explorer: CollectionItemsDto,
  ) => {
    const sampleMockRequest = new InitMockRequestTab(
      UntrackedItems.UNTRACKED + uuidv4(),
      workspaceId,
    );
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    let userSource = {};
    if (collection.activeSync && explorer?.source === "USER") {
      userSource = {
        currentBranch: collection.currentBranch
          ? collection.currentBranch
          : collection.primaryBranch,
        source: "USER",
      };
    }
    const requestObj = {
      collectionId: collection.id,
      workspaceId: workspaceId,
      ...userSource,
      folderId: explorer.id,
      items: {
        name: explorer.name,
        type: ItemType.FOLDER,
        id: explorer.id,
        items: {
          name: sampleMockRequest.getValue().name,
          type: sampleMockRequest.getValue().type,
          description: "",
          mockRequest: {
            method: sampleMockRequest.getValue().property.mockRequest?.method,
            url: "",
          } as RequestDto,
          ...(isGuestUser ? { updatedAt: new Date().toISOString() } : {}),
        },
      },
    };

    await this.collectionRepository.addRequestInFolder(
      requestObj.collectionId,
      requestObj.folderId,
      {
        ...requestObj.items.items,
        id: sampleMockRequest.getValue().id,
      },
    );

    if (isGuestUser === true) {
      const res = (await this.collectionRepository.readRequestInFolder(
        requestObj.collectionId,
        requestObj.folderId,
        sampleMockRequest.getValue().id,
      )) as CollectionItemsDto;
      res.id = uuidv4();
      this.collectionRepository.updateRequestInFolder(
        requestObj.collectionId,
        requestObj.folderId,
        sampleMockRequest.getValue().id,
        res,
      );

      sampleMockRequest.updateId(res.id);
      sampleMockRequest.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: explorer.id,
      });
      sampleMockRequest.updateIsSave(true);
      this.tabRepository.createTab(sampleMockRequest.getValue());

      scrollToTab("");
      // MixpanelEvent(Events.CREATE_REQUEST, {
      //   source: "Collection list",
      // });
      return;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response = await this.collectionService.addMockRequestInCollection(
      requestObj,
      baseUrl,
    );
    if (response.isSuccessful && response.data.data) {
      const request = response.data.data;

      this.collectionRepository.updateRequestInFolder(
        requestObj.collectionId,
        requestObj.folderId,
        sampleMockRequest.getValue().id,
        request,
      );

      sampleMockRequest.updateId(request.id);
      sampleMockRequest.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: explorer.id,
      });
      sampleMockRequest.updateIsSave(true);
      if ((collection.collectionType = CollectionTypeBaseEnum.MOCK)) {
        sampleMockRequest.updateLabel(CollectionTypeBaseEnum.MOCK);
      }
      // sampleMockRequest.updateUrl(collection?.mockCollectionUrl);
      this.tabRepository.createTab(sampleMockRequest.getValue());

      scrollToTab("");
      // MixpanelEvent(Events.CREATE_REQUEST, {
      //   source: "Collection list",
      // });
      return;
    } else {
      this.collectionRepository.deleteRequestInFolder(
        requestObj.collectionId,
        requestObj.folderId,
        sampleMockRequest.getValue().id,
      );
    }
  };

  /**
   * Handles creating a new AI request in a folder
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection in which new request is going to be created
   * @param explorer : - the folder in which new AI request is going to be created
   * @returns :void
   */
  private handleCreateAiRequestInFolder = async (
    workspaceId: string,
    collection: CollectionDto,
    explorer: CollectionItemsDto,
  ) => {
    const aiRequest = new InitAiRequestTab(
      UntrackedItems.UNTRACKED + uuidv4(),
      workspaceId,
    );
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    let userSource = {};
    if (collection.activeSync && explorer?.source === "USER") {
      userSource = {
        currentBranch: collection.currentBranch
          ? collection.currentBranch
          : collection.primaryBranch,
        source: "USER",
      };
    }
    const aiRequestObj = {
      collectionId: collection.id,
      workspaceId: workspaceId,
      ...userSource,
      folderId: explorer.id,
      items: {
        name: explorer.name,
        type: ItemType.FOLDER,
        id: explorer.id,
        items: {
          name: aiRequest.getValue().name,
          type: aiRequest.getValue().type,
          description: "",
          aiRequest: {
            aiModelProvider:
              aiRequest.getValue().property.aiRequest?.aiModelProvider,
            aiModelVariant:
              aiRequest.getValue().property.aiRequest?.aiModelVariant,
          } as AiRequestBaseInterface,
          ...(isGuestUser ? { updatedAt: new Date().toISOString() } : {}),
        },
      },
    };

    await this.collectionRepository.addRequestInFolder(
      aiRequestObj.collectionId,
      aiRequestObj.folderId,
      {
        ...aiRequestObj.items.items,
        id: aiRequest.getValue().id,
      },
    );

    if (isGuestUser === true) {
      const res = (await this.collectionRepository.readRequestInFolder(
        aiRequestObj.collectionId,
        aiRequestObj.folderId,
        aiRequest.getValue().id,
      )) as CollectionItemsDto;
      res.id = uuidv4();
      this.collectionRepository.updateRequestInFolder(
        aiRequestObj.collectionId,
        aiRequestObj.folderId,
        aiRequest.getValue().id,
        res,
      );

      aiRequest.updateId(res.id);
      aiRequest.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: explorer.id,
      });
      aiRequest.updateIsSave(true);
      this.tabRepository.createTab(aiRequest.getValue());

      scrollToTab("");
      // MixpanelEvent(Events.CREATE_REQUEST, {
      //   source: "Collection list",
      // });
      return;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response = await this.collectionService.addAiRequestInCollection(
      aiRequestObj,
      baseUrl,
    );
    if (response.isSuccessful && response.data.data) {
      const request = response.data.data;

      this.collectionRepository.updateRequestInFolder(
        aiRequestObj.collectionId,
        aiRequestObj.folderId,
        aiRequest.getValue().id,
        request,
      );

      aiRequest.updateId(request.id);
      aiRequest.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: explorer.id,
      });
      aiRequest.updateIsSave(true);
      this.tabRepository.createTab(aiRequest.getValue());

      scrollToTab("");
      // MixpanelEvent(Events.CREATE_REQUEST, {
      //   source: "Collection list",
      // });
      return;
    } else {
      this.collectionRepository.deleteRequestInFolder(
        aiRequestObj.collectionId,
        aiRequestObj.folderId,
        aiRequest.getValue().id,
      );
    }
  };

  /**
   * Handles creating a new web socket in a folder
   * @param workspaceId - the workspace id in which new web socket is going to be created
   * @param collection - the collection in which new web socket is going to be created
   * @param explorer - the folder in which new web socket is going to be created
   */
  private handleCreateWebSocketInFolder = async (
    workspaceId: string,
    collection: CollectionDto,
    explorer: CollectionItemsDto,
  ) => {
    const websocket = new InitWebSocketTab(
      UntrackedItems.UNTRACKED + uuidv4(),
      workspaceId,
    );
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    let userSource = {};
    if (collection.activeSync && explorer?.source === "USER") {
      userSource = {
        currentBranch: collection.currentBranch
          ? collection.currentBranch
          : collection.primaryBranch,
        source: "USER",
      };
    }
    const requestObj = {
      collectionId: collection.id,
      workspaceId: workspaceId,
      ...userSource,
      folderId: explorer.id,
      items: {
        name: explorer.name,
        type: ItemType.FOLDER,
        id: explorer.id,
        items: {
          name: websocket.getValue().name,
          type: websocket.getValue().type,
          description: "",
          websocket: {},
        },
        ...(isGuestUser ? { updatedAt: new Date().toISOString() } : {}),
      },
    };

    await this.collectionRepository.addRequestInFolder(
      requestObj.collectionId,
      requestObj.folderId,
      {
        ...requestObj.items.items,
        id: websocket.getValue().id,
      },
    );

    if (isGuestUser === true) {
      const res = (await this.collectionRepository.readRequestInFolder(
        requestObj.collectionId,
        requestObj.folderId,
        websocket.getValue().id,
      )) as CollectionItemsDto;
      res.id = uuidv4();
      this.collectionRepository.updateRequestInFolder(
        requestObj.collectionId,
        requestObj.folderId,
        websocket.getValue().id,
        res,
      );

      websocket.updateId(res.id);
      websocket.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: explorer.id,
      });
      websocket.updateIsSave(true);
      this.tabRepository.createTab(websocket.getValue());

      scrollToTab("");
      MixpanelEvent(Events.CREATE_REQUEST, {
        source: "Collection list",
      });
      return;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response = await this.collectionService.addSocketInCollection(
      requestObj,
      baseUrl,
    );
    if (response.isSuccessful && response.data.data) {
      const request = response.data.data;

      this.collectionRepository.updateRequestInFolder(
        requestObj.collectionId,
        requestObj.folderId,
        websocket.getValue().id,
        request,
      );

      websocket.updateId(request.id);
      websocket.updatePath({
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: explorer.id,
      });
      websocket.updateIsSave(true);
      this.tabRepository.createTab(websocket.getValue());

      scrollToTab("");
      MixpanelEvent(Events.CREATE_REQUEST, {
        source: "Collection list",
      });
      return;
    } else {
      this.collectionRepository.deleteRequestInFolder(
        requestObj.collectionId,
        requestObj.folderId,
        websocket.getValue().id,
      );
    }
  };

  /**
   * Handles creating a new socket io in a folder
   * @param _workspaceId - the workspace id in which new socket io is going to be created
   * @param _collection - the collection in which new socket io is going to be created
   * @param _folder - the folder in which new socket io is going to be created
   */
  private handleCreateSocketIoInFolder = async (
    _workspaceId: string,
    _collection: CollectionDto,
    _folder: CollectionItemsDto,
  ) => {
    const socketIoTab = new InitTab().socketIo(uuidv4(), _workspaceId);
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    const socketIoInFolderPayload: SocketIORequestCreateUpdateInFolderPayloadDtoInterface =
      {
        collectionId: _collection.id,
        workspaceId: _workspaceId,
        currentBranch:
          _collection.activeSync && _folder.source === "USER"
            ? _collection.currentBranch
            : undefined,
        source:
          _collection.activeSync && _folder.source === "USER"
            ? _folder.source
            : undefined,
        folderId: _folder.id,
        items: {
          name: _folder.name,
          type: CollectionItemTypeBaseEnum.FOLDER,
          id: _folder.id,
          items: {
            name: socketIoTab.getValue().name,
            type: CollectionItemTypeBaseEnum.SOCKETIO,
            description: "",
            socketio: {},
          },
          ...(isGuestUser ? { updatedAt: new Date().toISOString() } : {}),
        },
      };

    if (isGuestUser === true) {
      await this.collectionRepository.addRequestInFolder(
        socketIoInFolderPayload.collectionId,
        socketIoInFolderPayload.folderId as string,
        {
          ...socketIoInFolderPayload?.items?.items,
          id: socketIoTab.getValue().id,
        },
      );

      socketIoTab
        .updatePath({
          workspaceId: _workspaceId,
          collectionId: _collection.id,
          folderId: _folder.id,
        })
        .updateIsSave(true);
      this.tabRepository.createTab(socketIoTab.getValue());

      scrollToTab("");
      MixpanelEvent(Events.CREATE_REQUEST, {
        source: "Collection list",
      });
      return;
    }
    const baseUrl = await this.constructBaseUrl(_workspaceId);
    const response = await this.collectionService.addSocketIoInCollection(
      socketIoInFolderPayload,
      baseUrl,
    );
    if (response.isSuccessful && response.data.data) {
      const request = response.data.data;

      await this.collectionRepository.addRequestInFolder(
        socketIoInFolderPayload.collectionId,
        socketIoInFolderPayload.folderId as string,
        {
          ...request,
        },
      );

      socketIoTab
        .updateId(request?.id as string)
        .updatePath({
          workspaceId: _workspaceId,
          collectionId: _collection.id,
          folderId: _folder.id,
        })
        .updateIsSave(true);
      this.tabRepository.createTab(socketIoTab.getValue());

      scrollToTab("");
      MixpanelEvent(Events.CREATE_REQUEST, {
        source: "Collection list",
      });
      return;
    } else {
      this.collectionRepository.deleteRequestInFolder(
        socketIoInFolderPayload.collectionId,
        socketIoInFolderPayload.folderId as string,
        socketIoTab.getValue().id,
      );
    }
  };

  /**
   * Handles creating a new GraphQL request in a folder
   * @param _workspaceId - the workspace id in which new GraphQL request is going to be created
   * @param _collection - the collection in which new GraphQL request is going to be created
   * @param _folder - the folder in which new GraphQL request is going to be created
   */
  private handleCreateGraphqlInFolder = async (
    _workspaceId: string,
    _collection: CollectionDto,
    _folder: CollectionItemsDto,
  ) => {
    const graphqlTab = new InitTab().graphQl(uuidv4(), _workspaceId);
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    const graphqlInFolderPayload: GraphqlRequestCreateUpdateInFolderPayloadDtoInterface =
      {
        collectionId: _collection.id,
        workspaceId: _workspaceId,
        currentBranch:
          _collection.activeSync && _folder.source === "USER"
            ? _collection.currentBranch
            : undefined,
        source:
          _collection.activeSync && _folder.source === "USER"
            ? _folder.source
            : undefined,
        folderId: _folder.id,
        items: {
          name: _folder.name,
          type: CollectionItemTypeBaseEnum.FOLDER,
          id: _folder.id,
          items: {
            name: graphqlTab.getValue().name,
            type: CollectionItemTypeBaseEnum.GRAPHQL,
            description: "",
            graphql: {},
          },
          ...(isGuestUser ? { updatedAt: new Date().toISOString() } : {}),
        },
      };

    if (isGuestUser === true) {
      await this.collectionRepository.addRequestInFolder(
        graphqlInFolderPayload.collectionId,
        graphqlInFolderPayload.folderId as string,
        {
          ...graphqlInFolderPayload?.items?.items,
          id: graphqlTab.getValue().id,
        },
      );

      graphqlTab
        .updatePath({
          workspaceId: _workspaceId,
          collectionId: _collection.id,
          folderId: _folder.id,
        })
        .updateIsSave(true);
      this.tabRepository.createTab(graphqlTab.getValue());

      scrollToTab("");

      return;
    }
    const baseUrl = await this.constructBaseUrl(_workspaceId);
    const response = await this.collectionService.addGraphqlInCollection(
      graphqlInFolderPayload,
      baseUrl,
    );
    if (response.isSuccessful && response.data.data) {
      const request = response.data.data;

      await this.collectionRepository.addRequestInFolder(
        graphqlInFolderPayload.collectionId,
        graphqlInFolderPayload.folderId as string,
        {
          ...request,
        },
      );

      graphqlTab
        .updateId(request?.id as string)
        .updatePath({
          workspaceId: _workspaceId,
          collectionId: _collection.id,
          folderId: _folder.id,
        })
        .updateIsSave(true);
      this.tabRepository.createTab(graphqlTab.getValue());

      scrollToTab("");
      return;
    } else {
      this.collectionRepository.deleteRequestInFolder(
        graphqlInFolderPayload.collectionId,
        graphqlInFolderPayload.folderId as string,
        graphqlTab.getValue().id,
      );
    }
  };

  /**
   * Handles creating a new folder in a collection
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection in which new folder is going to be created
   * @returns :void
   */
  public handleCreateFolderInCollection = async (
    workspaceId: string,
    collection: CollectionDto,
  ): Promise<void> => {
    // Generate a new folder object with a unique ID, name, description, type, and an empty items array
    const folder = {
      id: UntrackedItems.UNTRACKED + uuidv4(),
      name: this.getNextName(collection.items, ItemType.FOLDER, "New Folder"),
      description: "",
      type: ItemType.FOLDER,
      items: [],
      updatedAt: new Date().toISOString(),
    };
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    // Determine the user source based on collection's active synchronization
    let userSource = {};
    if (collection?.activeSync) {
      userSource = {
        currentBranch: collection?.currentBranch
          ? collection?.currentBranch
          : collection?.primaryBranch,
        source: "USER",
      };
    }
    // Add the new folder to the collection locally
    await this.collectionRepository.addRequestOrFolderInCollection(
      collection.id,
      folder,
    );

    if (isGuestUser === true) {
      const data = {
        id: uuidv4(),
        name: this.getNextName(
          collection.items,
          ItemType.FOLDER,
          "New Folder",
        ) as string,
        description: "",
        type: ItemType.FOLDER,
        items: [],
      };

      const path = {
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: data.id,
      };

      const sampleFolder = new InitFolderTab(data.id, collection.workspaceId);

      sampleFolder.updateName(data.name);
      sampleFolder.updatePath(path);
      sampleFolder.updateIsSave(true);
      sampleFolder.updateTabType(TabPersistenceTypeEnum.PERMANENT);

      this.handleCreateTab(sampleFolder.getValue());
      scrollToTab("");
      addCollectionItem(data.id, "folder");
      // Update the locally added folder with server response
      const folderObj = data;
      await this.collectionRepository.updateRequestOrFolderInCollection(
        collection.id,
        folder.id,
        folderObj,
      );

      MixpanelEvent(Events.CREATE_FOLDER, {
        source: "Collection list",
      });
      return;
    }

    const baseUrl = await this.constructBaseUrl(workspaceId);
    // Add the folder in the collection on the Database
    const response = await this.collectionService.addFolderInCollection(
      workspaceId,
      collection.id,
      {
        ...userSource,
        name: folder.name,
        description: folder.description,
      },
      baseUrl,
    );

    // Update UI elements and handle navigation on success
    if (response.isSuccessful) {
      const path = {
        workspaceId: workspaceId,
        collectionId: collection.id,
        folderId: response.data.data.id,
        folderName: response.data.data.name,
      };

      const sampleFolder = new InitFolderTab(
        response.data.data.id,
        collection.workspaceId,
      );

      sampleFolder.updateName(response.data.data.name);
      sampleFolder.updatePath(path);
      sampleFolder.updateIsSave(true);
      sampleFolder.updateTabType(TabPersistenceTypeEnum.PERMANENT);
      if (collection?.collectionType === CollectionTypeBaseEnum.MOCK) {
        sampleFolder.updateLabel(CollectionTypeBaseEnum.MOCK);
      }
      this.handleCreateTab(sampleFolder.getValue());
      scrollToTab("");
      addCollectionItem(response.data.data.id, "folder");

      // Update the locally added folder with server response
      const folderObj = response.data.data;
      await this.collectionRepository.updateRequestOrFolderInCollection(
        collection.id,
        folder.id,
        folderObj,
      );

      MixpanelEvent(Events.CREATE_FOLDER, {
        source: "Collection list",
      });
    } else {
      // Show error notification and clean up by deleting the folder locally on failure.
      notifications.error("Failed to create folder. Please try again.");
      this.collectionRepository.deleteRequestOrFolderInCollection(
        collection.id,
        folder.id,
      );
    }
  };

  /**
   * Handles renaming a collection
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection going to be renamed
   * @param newCollectionName :string - the new name of the collection
   */
  private handleRenameCollection = async (
    workspaceId: string,
    collection: CollectionDto,
    newCollectionName: string,
  ) => {
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser !== true) {
      if (newCollectionName) {
        const baseUrl = await this.constructBaseUrl(workspaceId);
        const response = await this.collectionService.updateCollectionData(
          collection.id,
          workspaceId,
          { name: newCollectionName },
          baseUrl,
        );
        if (response.isSuccessful) {
          this.collectionRepository.updateCollection(
            collection.id,
            response.data.data,
          );
          this.updateTab(collection.id, {
            name: newCollectionName,
          });
          MixpanelEvent(Events.RENAME_COLLECTION, {
            source: "Collection list",
          });
        } else if (response.message === "Network Error") {
          notifications.error(response.message);
        } else {
          notifications.error("Failed to rename collection. Please try again.");
        }
      }
    } else {
      if (newCollectionName) {
        const response = {
          data: {
            name: newCollectionName,
            updatedAt: new Date().toISOString(),
          },
        };
        await this.collectionRepository.updateCollection(
          collection.id,
          response.data,
        );
        this.updateTab(collection.id, { name: newCollectionName });
        notifications.success("Collection renamed successfully!");
      } else {
        notifications.error("Failed to rename collection. Please try again.");
      }
    }
  };

  /**
   * Handles renaming a folder
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection in which the folder is saved
   * @param explorer : - the folder going to be renamed
   * @param newFolderName :string - the new name of the folder
   */
  private handleRenameFolder = async (
    workspaceId: string,
    collection: CollectionDto,
    explorer: CollectionItemsDto,
    newFolderName: string,
  ) => {
    if (newFolderName) {
      let userSource = {};
      if (collection.activeSync && explorer?.source === "USER") {
        userSource = {
          currentBranch: collection.currentBranch
            ? collection.currentBranch
            : collection.primaryBranch,
          source: "USER",
        };
      }
      let isGuestUser;
      isGuestUserActive.subscribe((value) => {
        isGuestUser = value;
      });

      if (isGuestUser !== true) {
        const baseUrl = await this.constructBaseUrl(workspaceId);
        const response = await this.collectionService.updateFolderInCollection(
          workspaceId,
          collection.id,
          explorer.id,
          {
            ...userSource,
            name: newFolderName,
          },
          baseUrl,
        );
        if (response.isSuccessful) {
          this.collectionRepository.updateRequestOrFolderInCollection(
            collection.id,
            explorer.id,
            response.data.data,
          );

          this.updateTab(explorer.id, {
            name: newFolderName,
          });
          MixpanelEvent(Events.RENAME_FOLDER, {
            source: "Collection list",
          });
        }
      } else {
        this.updateTab(collection.id, { name: newFolderName });
        const res =
          await this.collectionRepository.readRequestOrFolderInCollection(
            collection.id,
            explorer.id,
          );
        if (res) {
          res.name = newFolderName;
          res.updatedAt = new Date().toISOString();
        }
        this.collectionRepository.updateRequestOrFolderInCollection(
          collection.id,
          explorer.id,
          res,
        );
        // notifications.success("Folder renamed successfully!");

        this.updateTab(explorer.id, {
          name: newFolderName,
        });
        MixpanelEvent(Events.RENAME_FOLDER, {
          source: "Collection list",
        });
      }
    }
  };

  /**
   * Handles opening a request on a tab
   * @param request : - The request going to be opened on tab
   * @param path : - The path to the request
   */
  public handleOpenRequest = (
    workspaceId: string,
    collection: CollectionDto,
    folder: CollectionItemsDto,
    request: CollectionItemsDto,
  ) => {
    const requestTabAdapter = new RequestTabAdapter();
    const adaptedRequest = requestTabAdapter.adapt(
      workspaceId || "",
      collection?.id || "",
      folder?.id || "",
      request,
    );
    adaptedRequest.persistence = TabPersistenceTypeEnum.TEMPORARY;
    this.tabRepository.createTab(adaptedRequest);
    scrollToTab(request.id);
  };

  /**
   * Handles opening a mock request on a tab
   * @param request : - The request going to be opened on tab
   * @param path : - The path to the request
   */
  public handleOpenMockRequest = (
    workspaceId: string,
    collection: CollectionDto,
    folder: CollectionItemsDto,
    request: CollectionItemsDto,
  ) => {
    const requestTabAdapter = new RequestMockTabAdapter();
    // Update the request data before passing to adapter
    if (request?.items) {
      request.items.forEach((data) => {
        // if (data.mockRequestResponse?.selectedResponseBodyType) {
        // Ensure state object exists
        if (!data.state) {
          data.state = {};
        }
        const bodyType = this.setResponseBodyType(
          data.mockRequestResponse.selectedResponseBodyType,
        );

        data.state.responseBodyLanguage = bodyType.responseBodyLanguage;
        data.state.responseBodyFormatter = "Pretty";
        data.state.responseNavigation = "Response";
        // }
      });
    } else {
      request.items = [];
    }
    const adaptedRequest = requestTabAdapter.adapt(
      workspaceId || "",
      collection?.id || "",
      folder?.id || "",
      request,
    );
    adaptedRequest.persistence = TabPersistenceTypeEnum.TEMPORARY;
    this.tabRepository.createTab(adaptedRequest);
    scrollToTab(request.id);
  };

  /**
   * Handles opening a request on a tab
   * @param request : - The request going to be opened on tab
   * @param path : - The path to the request
   */
  private handleOpenSavedRequest = (
    workspaceId: string,
    collection: CollectionDto,
    folder: CollectionItemsDto,
    _request: CollectionItemsDto,
    _savedRequest: CollectionItemsDto,
  ) => {
    const requestSavedTabAdapter = new RequestSavedTabAdapter();
    const adaptedRequest = requestSavedTabAdapter.adapt(
      workspaceId || "",
      collection?.id || "",
      folder?.id || "",
      _request?.id,
      _savedRequest,
    );
    adaptedRequest.persistence = TabPersistenceTypeEnum.TEMPORARY;
    this.tabRepository.createTab(adaptedRequest);
    scrollToTab(_savedRequest.id);
  };

  /**
   * Handles opening a request on a tab
   * @param request : - The request going to be opened on tab
   * @param path : - The path to the request
   */
  public handleOpenGraphqlTab = (
    workspaceId: string,
    collection: CollectionDto,
    folder: CollectionItemsDto,
    _graphql: CollectionItemsDto,
  ) => {
    const requestTabAdapter = new GraphqlTabAdapter();
    const adaptedRequest = requestTabAdapter.adapt(
      workspaceId || "",
      collection?.id || "",
      folder?.id || "",
      _graphql,
    );
    adaptedRequest.persistence = TabPersistenceTypeEnum.TEMPORARY;
    this.tabRepository.createTab(adaptedRequest);
    scrollToTab(_graphql.id);
  };

  /**
   * Handles opening a request on a tab
   * @param request : - The request going to be opened on tab
   * @param path : - The path to the request
   */
  public handleOpenWebSocket = (
    workspaceId: string,
    collection: CollectionDto,
    folder: CollectionItemsDto,
    websocket: CollectionItemsDto,
  ) => {
    const socketTabAdapter = new SocketTabAdapter();
    const adaptedSocket = socketTabAdapter.adapt(
      workspaceId || "",
      collection?.id || "",
      folder?.id || "",
      websocket,
    );
    adaptedSocket.persistence = TabPersistenceTypeEnum.TEMPORARY;
    this.tabRepository.createTab(adaptedSocket);
    scrollToTab(websocket.id);
  };

  /**
   * Handles opening a AI Request on a tab
   * @param aiRequest : - The AI Request going to be opened on tab
   * @param path : - The path to the AI Request
   */
  public handleOpenAiRequest = (
    workspaceId: string,
    collection: CollectionDto,
    folder: CollectionItemsDto,
    aiRequest: CollectionItemsDto,
  ) => {
    const aiRequestTabAdapter = new AiRequestTabAdapter();
    const adaptedAiRequest = aiRequestTabAdapter.adapt(
      workspaceId || "",
      collection?.id || "",
      folder?.id || "",
      aiRequest,
    );
    adaptedAiRequest.persistence = TabPersistenceTypeEnum.TEMPORARY;
    this.tabRepository.createTab(adaptedAiRequest);
    scrollToTab("");
  };

  /**
   * Handles opening a socket io on a tab
   * @param _workspaceId  Workspace id of which tab belongs to.
   * @param _collection  Collection of which tab belongs to.
   * @param _folder Folder of which tab belongs to.
   * @param _socketIo Socket Io meta data
   */
  public handleOpenSocketIoTab = (
    _workspaceId: string,
    _collection: CollectionDto,
    _folder: CollectionItemsDto,
    _socketIo: CollectionItemsDto,
  ) => {
    const socketIoTabAdapter = new SocketIoTabAdapter();
    const adaptedSocketIo = socketIoTabAdapter.adapt(
      _workspaceId || "",
      _collection?.id || "",
      _folder?.id || "",
      _socketIo,
    );
    adaptedSocketIo.persistence = TabPersistenceTypeEnum.TEMPORARY;
    this.tabRepository.createTab(adaptedSocketIo);
    scrollToTab(_socketIo.id);
  };

  public handleOpenFolder = (
    workspaceId: string,
    collection: CollectionDto,
    folder: CollectionItemsDto,
  ) => {
    const folderTab = new FolderTabAdapter().adapt(
      workspaceId,
      collection.id,
      folder,
      collection.collectionType,
    );
    this.handleCreateTab(folderTab);
    scrollToTab(folder.id);
  };

  public handleOpenCollection = (
    workspaceId: string,
    collection: CollectionDto,
    navigation: CollectionNavigationTabEnum,
  ) => {
    const collectionTabAdapter = new CollectionTabAdapter().adapt(
      workspaceId,
      collection,
      navigation,
    );
    collectionTabAdapter.persistence = TabPersistenceTypeEnum.TEMPORARY;
    this.tabRepository.createTab(collectionTabAdapter);
    scrollToTab(collection.id);
  };

  public handleOpenMockHistory = (
    workspaceId: string,
    collection: CollectionDto,
  ) => {
    const mockHistroyTab = new MockHistoryTabAdapter().adapt(
      workspaceId,
      collection.id,
    );
    this.handleCreateTab(mockHistroyTab);
    scrollToTab(mockHistroyTab.id);
  };

  /**
   * Handles renaming a request
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection in which the request is saved
   * @param folder : - the folder in which the request is saved(if request if saved inside a folder)
   * @param request : - the request which is going to be renamed
   * @param newRequestName : - the new name of the request
   */
  private handleRenameRequest = async (
    workspaceId: string,
    collection: CollectionDto,
    folder: CollectionItemsDto,
    request: CollectionItemsDto,
    newRequestName: string,
  ) => {
    let userSource = {};
    if (request.source === "USER") {
      userSource = {
        currentBranch: collection.currentBranch
          ? collection.currentBranch
          : collection.primaryBranch,
        source: "USER",
      };
    }
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      if (collection.id && workspaceId && !folder.id) {
        const response =
          await this.collectionRepository.readRequestOrFolderInCollection(
            collection.id,
            request.id,
          );
        const storage = request;
        storage.name = newRequestName;
        response.updatedAt = new Date().toISOString();
        await this.collectionRepository.updateRequestOrFolderInCollection(
          collection.id,
          request.id,
          { name: newRequestName, updatedAt: new Date().toISOString() },
        );
        this.updateTab(request.id, {
          name: newRequestName,
        });
        MixpanelEvent(Events.RENAME_REQUEST, {
          source: "Collection list",
        });
      } else if (collection.id && workspaceId && folder.id) {
        const response = await this.collectionRepository.readRequestInFolder(
          collection.id,
          folder.id,
          request.id,
        );
        const storage = request;
        storage.name = newRequestName;
        response.updatedAt = new Date().toISOString();
        await this.collectionRepository.updateRequestInFolder(
          collection.id,
          folder.id,
          request.id,
          { name: newRequestName, updatedAt: new Date().toISOString() },
        );
        this.updateTab(request.id, {
          name: newRequestName,
        });
        MixpanelEvent(Events.RENAME_REQUEST, {
          source: "Collection list",
        });
      }
      return;
    }

    if (newRequestName) {
      if (collection.id && workspaceId && !folder.id) {
        const storage = request;
        storage.name = newRequestName;
        const baseUrl = await this.constructBaseUrl(workspaceId);
        const response = await this.collectionService.updateRequestInCollection(
          request.id,
          {
            collectionId: collection.id,
            workspaceId: workspaceId,
            ...userSource,
            items: storage,
          },
          baseUrl,
        );
        if (response.isSuccessful) {
          this.collectionRepository.updateRequestOrFolderInCollection(
            collection.id,
            request.id,
            response.data.data,
          );
          this.updateTab(request.id, {
            name: newRequestName,
          });
          MixpanelEvent(Events.RENAME_REQUEST, {
            source: "Collection list",
          });
        }
      } else if (collection.id && workspaceId && folder.id) {
        const storage = request;
        storage.name = newRequestName;
        const baseUrl = await this.constructBaseUrl(workspaceId);
        const response = await this.collectionService.updateRequestInCollection(
          request.id,
          {
            collectionId: collection.id,
            workspaceId: workspaceId,
            ...userSource,
            folderId: folder.id,
            items: {
              name: folder.name,
              id: folder.id,
              type: ItemType.FOLDER,
              items: storage,
            },
          } as CreateApiRequestPostBody,
          baseUrl,
        );
        if (response.isSuccessful) {
          this.collectionRepository.updateRequestInFolder(
            collection.id,
            folder.id,
            request.id,
            response.data.data,
          );
          this.updateTab(request.id, {
            name: newRequestName,
          });
          MixpanelEvent(Events.RENAME_REQUEST, {
            source: "Collection list",
          });
        }
      }
    }
  };

  /**
   * Handles renaming a AI request
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection in which the request is saved
   * @param folder : - the folder in which the request is saved(if AI request if saved inside a folder)
   * @param request : - the AI request which is going to be renamed
   * @param newRequestName : - the new name of the request
   */
  private handleRenameAiRequest = async (
    workspaceId: string,
    collection: CollectionDto,
    folder: CollectionItemsDto,
    aiRequest: CollectionItemsDto,
    newRequestName: string,
  ) => {
    let userSource = {};
    if (aiRequest.source === "USER") {
      userSource = {
        currentBranch: collection.currentBranch
          ? collection.currentBranch
          : collection.primaryBranch,
        source: "USER",
      };
    }
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      if (collection.id && workspaceId && !folder.id) {
        const response =
          await this.collectionRepository.readRequestOrFolderInCollection(
            collection.id,
            aiRequest.id,
          );
        const storage = aiRequest;
        storage.name = newRequestName;
        response.updatedAt = new Date().toISOString();
        await this.collectionRepository.updateRequestOrFolderInCollection(
          collection.id,
          aiRequest.id,
          { name: newRequestName, updatedAt: new Date().toISOString() },
        );
        this.updateTab(aiRequest.id, {
          name: newRequestName,
        });
        // MixpanelEvent(Events.RENAME_REQUEST, {
        //   source: "Collection list",
        // });
      } else if (collection.id && workspaceId && folder.id) {
        const response = await this.collectionRepository.readRequestInFolder(
          collection.id,
          folder.id,
          aiRequest.id,
        );
        const storage = aiRequest;
        storage.name = newRequestName;
        response.updatedAt = new Date().toISOString();
        await this.collectionRepository.updateRequestInFolder(
          collection.id,
          folder.id,
          aiRequest.id,
          { name: newRequestName, updatedAt: new Date().toISOString() },
        );
        this.updateTab(aiRequest.id, {
          name: newRequestName,
        });
        // MixpanelEvent(Events.RENAME_REQUEST, {
        //   source: "Collection list",
        // });
      }
      return;
    }

    if (newRequestName) {
      if (collection.id && workspaceId && !folder.id) {
        const storage = aiRequest;
        storage.name = newRequestName;
        const baseUrl = await this.constructBaseUrl(workspaceId);
        const response =
          await this.collectionService.updateAiRequestInCollection(
            aiRequest.id,
            {
              collectionId: collection.id,
              workspaceId: workspaceId,
              ...userSource,
              items: storage,
            },
            baseUrl,
          );
        if (response.isSuccessful) {
          this.collectionRepository.updateRequestOrFolderInCollection(
            collection.id,
            aiRequest.id,
            response.data.data,
          );
          this.updateTab(aiRequest.id, {
            name: newRequestName,
          });
          // MixpanelEvent(Events.RENAME_REQUEST, {
          //   source: "Collection list",
          // });
        }
      } else if (collection.id && workspaceId && folder.id) {
        const storage = aiRequest;
        storage.name = newRequestName;
        const baseUrl = await this.constructBaseUrl(workspaceId);
        const response =
          await this.collectionService.updateAiRequestInCollection(
            aiRequest.id,
            {
              collectionId: collection.id,
              workspaceId: workspaceId,
              ...userSource,
              folderId: folder.id,
              items: {
                name: folder.name,
                id: folder.id,
                type: ItemType.FOLDER,
                items: storage,
              },
            },
            baseUrl,
          );
        if (response.isSuccessful) {
          this.collectionRepository.updateRequestInFolder(
            collection.id,
            folder.id,
            aiRequest.id,
            response.data.data,
          );
          this.updateTab(aiRequest.id, {
            name: newRequestName,
          });
          // MixpanelEvent(Events.RENAME_REQUEST, {
          //   source: "Collection list",
          // });
        }
      }
    }
  };

  /**
   * Handles renaming a mock request
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection in which the mock request is saved
   * @param folder : - the folder in which the request is saved(if request if saved inside a folder)
   * @param request : - the request which is going to be renamed
   * @param newRequestName : - the new name of the request
   */
  private handleRenameMockRequest = async (
    workspaceId: string,
    collection: CollectionDto,
    folder: CollectionItemsDto,
    request: CollectionItemsDto,
    newRequestName: string,
  ) => {
    let userSource = {};
    if (request.source === "USER") {
      userSource = {
        currentBranch: collection.currentBranch
          ? collection.currentBranch
          : collection.primaryBranch,
        source: "USER",
      };
    }
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      if (collection.id && workspaceId && !folder.id) {
        const response =
          await this.collectionRepository.readRequestOrFolderInCollection(
            collection.id,
            request.id,
          );
        const storage = request;
        storage.name = newRequestName;
        response.updatedAt = new Date().toISOString();
        await this.collectionRepository.updateRequestOrFolderInCollection(
          collection.id,
          request.id,
          { name: newRequestName, updatedAt: new Date().toISOString() },
        );
        this.updateTab(request.id, {
          name: newRequestName,
        });
        MixpanelEvent(Events.RENAME_REQUEST, {
          source: "Collection list",
        });
      } else if (collection.id && workspaceId && folder.id) {
        const response = await this.collectionRepository.readRequestInFolder(
          collection.id,
          folder.id,
          request.id,
        );
        const storage = request;
        storage.name = newRequestName;
        response.updatedAt = new Date().toISOString();
        await this.collectionRepository.updateRequestInFolder(
          collection.id,
          folder.id,
          request.id,
          { name: newRequestName, updatedAt: new Date().toISOString() },
        );
        this.updateTab(request.id, {
          name: newRequestName,
        });
        MixpanelEvent(Events.RENAME_REQUEST, {
          source: "Collection list",
        });
      }
      return;
    }

    if (newRequestName) {
      if (collection.id && workspaceId && !folder.id) {
        const storage = request;
        storage.name = newRequestName;
        const baseUrl = await this.constructBaseUrl(workspaceId);
        const response =
          await this.collectionService.updateMockRequestInCollection(
            request.id,
            {
              collectionId: collection.id,
              workspaceId: workspaceId,
              ...userSource,
              items: storage,
            },
            baseUrl,
          );
        if (response.isSuccessful) {
          this.collectionRepository.updateRequestOrFolderInCollection(
            collection.id,
            request.id,
            response.data.data,
          );
          this.updateTab(request.id, {
            name: newRequestName,
          });
          // MixpanelEvent(Events.RENAME_REQUEST, {
          //   source: "Collection list",
          // });
        }
      } else if (collection.id && workspaceId && folder.id) {
        const storage = request;
        storage.name = newRequestName;
        const baseUrl = await this.constructBaseUrl(workspaceId);
        const response =
          await this.collectionService.updateMockRequestInCollection(
            request.id,
            {
              collectionId: collection.id,
              workspaceId: workspaceId,
              ...userSource,
              folderId: folder.id,
              items: {
                name: folder.name,
                id: folder.id,
                type: ItemType.FOLDER,
                items: storage,
              },
            },
            baseUrl,
          );
        if (response.isSuccessful) {
          this.collectionRepository.updateRequestInFolder(
            collection.id,
            folder.id,
            request.id,
            response.data.data,
          );
          this.updateTab(request.id, {
            name: newRequestName,
          });
          // MixpanelEvent(Events.RENAME_REQUEST, {
          //   source: "Collection list",
          // });
        }
      }
    }
  };

  /**
   * Handles renaming a saved request
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection in which the request is saved
   * @param folder : - the folder in which the request is saved(if request if saved inside a folder)
   * @param request : - the request in which the response is saved
   * @param requestResponse : - the requestResponse which is going to be renamed.
   * @param newRequestName : - the new name of the saved request
   */
  private handleRenameSavedRequest = async (
    workspaceId: string,
    collection: CollectionDto,
    folder: CollectionItemsDto,
    request: CollectionItemsDto,
    requestResponse: CollectionItemsDto,
    newRequestName: string,
  ) => {
    let userSource = {};
    if (request.source === "USER") {
      userSource = {
        currentBranch: collection.currentBranch
          ? collection.currentBranch
          : collection.primaryBranch,
        source: "USER",
      };
    }
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      if (collection.id && workspaceId && !folder.id) {
        await this.collectionRepository.updateSavedRequestInCollection(
          collection.id,
          request.id,
          requestResponse.id,
          { name: newRequestName, updatedAt: new Date().toISOString() },
        );
        await this.updateTab(requestResponse.id, {
          name: newRequestName,
        });
        MixpanelEvent(Events.RENAME_REQUEST, {
          source: "Collection list",
        });
      } else if (collection.id && workspaceId && folder.id) {
        await this.collectionRepository.updateSavedRequestInFolder(
          collection.id,
          folder.id,
          request.id,
          requestResponse.id,
          { name: newRequestName, updatedAt: new Date().toISOString() },
        );
        await this.updateTab(requestResponse.id, {
          name: newRequestName,
        });
        MixpanelEvent(Events.RENAME_REQUEST, {
          source: "Collection list",
        });
      }
      return;
    }

    if (newRequestName) {
      if (collection.id && workspaceId && !folder.id) {
        // const storage = request;
        // storage.name = newRequestName;
        const baseUrl = await this.constructBaseUrl(workspaceId);
        const response =
          await this.collectionService.updateSavedRequestInCollection(
            requestResponse.id,
            {
              collectionId: collection.id,
              workspaceId: workspaceId,
              requestId: request.id,
              name: newRequestName,
            },
            baseUrl,
          );
        if (response.isSuccessful) {
          this.collectionRepository.updateSavedRequestInCollection(
            collection.id,
            request.id,
            requestResponse.id,
            { name: newRequestName },
          );
          this.updateTab(requestResponse.id, {
            name: newRequestName,
          });
          MixpanelEvent(Events.RENAME_RESPONSE, {
            source: "Collection list",
          });
        }
      } else if (collection.id && workspaceId && folder.id) {
        const baseUrl = await this.constructBaseUrl(workspaceId);
        const response =
          await this.collectionService.updateSavedRequestInCollection(
            requestResponse.id,
            {
              collectionId: collection.id,
              workspaceId: workspaceId,
              folderId: folder.id,
              requestId: request.id,
              name: newRequestName,
            } as CreateApiRequestPostBody,
            baseUrl,
          );
        if (response.isSuccessful) {
          this.collectionRepository.updateSavedRequestInFolder(
            collection.id,
            folder.id,
            request.id,
            requestResponse.id,
            { name: newRequestName },
          );
          this.updateTab(requestResponse.id, {
            name: newRequestName,
          });
          MixpanelEvent(Events.RENAME_RESPONSE, {
            source: "Collection list",
          });
        }
      }
    }
  };

  /**
   * Handles renaming a web socket
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection in which the request is saved
   * @param folder : - the folder in which the request is saved(if request if saved inside a folder)
   * @param request : - the request which is going to be renamed
   * @param newRequestName : - the new name of the request
   */
  private handleRenameWebSocket = async (
    workspaceId: string,
    collection: CollectionDto,
    folder: CollectionItemsDto,
    websocket: CollectionItemsDto,
    newWebSocketName: string,
  ) => {
    let userSource = {};
    if (websocket.source === "USER") {
      userSource = {
        currentBranch: collection.currentBranch
          ? collection.currentBranch
          : collection.primaryBranch,
        source: "USER",
      };
    }
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      if (collection.id && workspaceId && !folder.id) {
        const response =
          await this.collectionRepository.readRequestOrFolderInCollection(
            collection.id,
            websocket.id,
          );
        const storage = websocket;
        storage.name = newWebSocketName;
        await this.collectionRepository.updateRequestOrFolderInCollection(
          collection.id,
          websocket.id,
          { name: newWebSocketName, updatedAt: new Date().toISOString() },
        );
        this.updateTab(websocket.id, {
          name: newWebSocketName,
        });
        MixpanelEvent(Events.RENAME_REQUEST, {
          source: "Collection list",
        });
      } else if (collection.id && workspaceId && folder.id) {
        const response = await this.collectionRepository.readRequestInFolder(
          collection.id,
          folder.id,
          websocket.id,
        );
        const storage = websocket;
        storage.name = newWebSocketName;
        await this.collectionRepository.updateRequestInFolder(
          collection.id,
          folder.id,
          websocket.id,
          { name: newWebSocketName, updatedAt: new Date().toISOString() },
        );
        this.updateTab(websocket.id, {
          name: newWebSocketName,
        });
        MixpanelEvent(Events.RENAME_REQUEST, {
          source: "Collection list",
        });
      }
      return;
    }

    if (newWebSocketName) {
      if (collection.id && workspaceId && !folder.id) {
        const storage = websocket;
        storage.name = newWebSocketName;
        const baseUrl = await this.constructBaseUrl(workspaceId);
        const response = await this.collectionService.updateSocketInCollection(
          websocket.id,
          {
            collectionId: collection.id,
            workspaceId: workspaceId,
            ...userSource,
            items: storage,
          },
          baseUrl,
        );
        if (response.isSuccessful) {
          this.collectionRepository.updateRequestOrFolderInCollection(
            collection.id,
            websocket.id,
            response.data.data,
          );
          this.updateTab(websocket.id, {
            name: newWebSocketName,
          });
          MixpanelEvent(Events.RENAME_REQUEST, {
            source: "Collection list",
          });
        }
      } else if (collection.id && workspaceId && folder.id) {
        const storage = websocket;
        storage.name = newWebSocketName;
        const baseUrl = await this.constructBaseUrl(workspaceId);
        const response = await this.collectionService.updateSocketInCollection(
          websocket.id,
          {
            collectionId: collection.id,
            workspaceId: workspaceId,
            ...userSource,
            folderId: folder.id,
            items: {
              name: folder.name,
              id: folder.id,
              type: ItemType.FOLDER,
              items: storage,
            },
          },
          baseUrl,
        );
        if (response.isSuccessful) {
          this.collectionRepository.updateRequestInFolder(
            collection.id,
            folder.id,
            websocket.id,
            response.data.data,
          );
          this.updateTab(websocket.id, {
            name: newWebSocketName,
          });
          MixpanelEvent(Events.RENAME_REQUEST, {
            source: "Collection list",
          });
        }
      }
    }
  };

  /**
   * Handles renaming a socket io
   * @param _workspaceId
   * @param _collection The collection in which the request is saved
   * @param _folder The folder in which the request is saved(if request if saved inside a folder)
   * @param _socketIo The request which is going to be renamed
   * @param _newSocketIoName The new name of the request
   */
  private handleRenameSocketIO = async (
    _workspaceId: string,
    _collection: CollectionDto,
    _folder: CollectionItemsDto,
    _socketIo: CollectionItemsDto,
    _newSocketIoName: string,
  ) => {
    let isGuestUser = true;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      if (_collection.id && _workspaceId && !_folder.id) {
        const response =
          await this.collectionRepository.readRequestOrFolderInCollection(
            _collection.id,
            _socketIo.id,
          );
        if (response) {
          response.name = _newSocketIoName;
        }
        const newResponse = {
          ...response,
          updatedAt: new Date().toISOString(),
        };
        await this.collectionRepository.updateRequestOrFolderInCollection(
          _collection.id,
          _socketIo.id,
          newResponse,
        );
        this.updateTab(_socketIo.id, {
          name: _newSocketIoName,
        });
        MixpanelEvent(Events.RENAME_REQUEST, {
          source: "Collection list",
        });
        return;
      }
      if (_collection.id && _workspaceId && _folder.id) {
        const response = await this.collectionRepository.readRequestInFolder(
          _collection.id,
          _folder.id,
          _socketIo.id,
        );
        if (response) {
          response.name = _newSocketIoName;
        }
        const newResponse = {
          ...response,
          updatedAt: new Date().toISOString(),
        };
        await this.collectionRepository.updateRequestInFolder(
          _collection.id,
          _folder.id,
          _socketIo.id,
          newResponse,
        );
        this.updateTab(_socketIo.id, {
          name: _newSocketIoName,
        });
        MixpanelEvent(Events.RENAME_REQUEST, {
          source: "Collection list",
        });
        return;
      }
      return;
    }
    if (!_newSocketIoName) {
      return;
    }
    if (_collection.id && _workspaceId && !_folder.id) {
      const baseUrl = await this.constructBaseUrl(_workspaceId);
      const response = await this.collectionService.updateSocketIoInCollection(
        _socketIo.id,
        {
          collectionId: _collection.id,
          workspaceId: _workspaceId,
          currentBranch:
            _collection.activeSync && _socketIo.source === "USER"
              ? _collection.currentBranch
              : undefined,
          source:
            _collection.activeSync && _socketIo.source === "USER"
              ? _socketIo.source
              : undefined,
          items: {
            createdAt: _socketIo.createdAt,
            createdBy: _socketIo.createdBy,
            description: _socketIo.description,
            id: _socketIo.id,
            isDeleted: _socketIo.isDeleted,
            name: _newSocketIoName,
            socketio: _socketIo.socketio,
            source: _socketIo.source,
            type: _socketIo.type,
            updatedAt: _socketIo.updatedAt,
            updatedBy: _socketIo.updatedBy,
          },
        } as SocketIORequestCreateUpdateInCollectionPayloadDtoInterface,
        baseUrl,
      );
      if (!response?.isSuccessful) {
        return;
      }
      this.collectionRepository.updateRequestOrFolderInCollection(
        _collection.id,
        _socketIo.id,
        response.data.data,
      );
      this.updateTab(_socketIo.id, {
        name: _newSocketIoName,
      });
      MixpanelEvent(Events.RENAME_REQUEST, {
        source: "Collection list",
      });
      return;
    }
    if (_collection.id && _workspaceId && _folder.id) {
      const baseUrl = await this.constructBaseUrl(_workspaceId);
      const response = await this.collectionService.updateSocketIoInCollection(
        _socketIo.id,
        {
          collectionId: _collection.id,
          workspaceId: _workspaceId,
          currentBranch:
            _collection?.activeSync && _socketIo?.source === "USER"
              ? _collection?.currentBranch
              : undefined,
          source:
            _collection?.activeSync && _socketIo?.source === "USER"
              ? _socketIo?.source
              : undefined,
          folderId: _folder.id,
          items: {
            name: _folder.name,
            id: _folder.id,
            type: CollectionItemTypeBaseEnum.FOLDER,
            items: {
              createdAt: _socketIo.createdAt,
              createdBy: _socketIo.createdBy,
              description: _socketIo.description,
              id: _socketIo.id,
              isDeleted: _socketIo.isDeleted,
              name: _newSocketIoName,
              socketio: _socketIo.socketio,
              source: _socketIo.source,
              type: _socketIo.type,
              updatedAt: _socketIo.updatedAt,
              updatedBy: _socketIo.updatedBy,
            },
          },
        } as SocketIORequestCreateUpdateInFolderPayloadDtoInterface,
        baseUrl,
      );
      if (!response?.isSuccessful) {
        return;
      }
      this.collectionRepository.updateRequestInFolder(
        _collection.id,
        _folder.id,
        _socketIo.id,
        response.data.data,
      );
      this.updateTab(_socketIo.id, {
        name: _newSocketIoName,
      });
      MixpanelEvent(Events.RENAME_REQUEST, {
        source: "Collection list",
      });
    }
  };

  /**
   * Handles renaming a GraphQL
   * @param _workspaceId
   * @param _collection The collection in which the GraphQL request is saved
   * @param _folder The folder in which the GraphQL request is saved (if request if saved inside a folder)
   * @param _graphql The GraphQL request which is going to be renamed
   * @param _newSocketIoName The new name of the GraphQL request
   */
  private handleRenameGraphql = async (
    _workspaceId: string,
    _collection: CollectionDto,
    _folder: CollectionItemsDto,
    _graphql: CollectionItemsDto,
    _newGraphqlName: string,
  ) => {
    let isGuestUser = true;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      if (_collection.id && _workspaceId && !_folder.id) {
        const response =
          await this.collectionRepository.readRequestOrFolderInCollection(
            _collection.id,
            _graphql.id,
          );
        if (response) {
          response.name = _newGraphqlName;
        }
        const newResponse = {
          ...response,
          updatedAt: new Date().toISOString(),
        };
        await this.collectionRepository.updateRequestOrFolderInCollection(
          _collection.id,
          _graphql.id,
          newResponse,
        );
        this.updateTab(_graphql.id, {
          name: _newGraphqlName,
        });
        MixpanelEvent(Events.RENAME_REQUEST, {
          source: "Collection list",
        });
        return;
      }
      if (_collection.id && _workspaceId && _folder.id) {
        const response = await this.collectionRepository.readRequestInFolder(
          _collection.id,
          _folder.id,
          _graphql.id,
        );
        if (response) {
          response.name = _newGraphqlName;
        }
        const newResponse = {
          ...response,
          updatedAt: new Date().toISOString(),
        };
        await this.collectionRepository.updateRequestInFolder(
          _collection.id,
          _folder.id,
          _graphql.id,
          newResponse,
        );
        this.updateTab(_graphql.id, {
          name: _newGraphqlName,
        });
        MixpanelEvent(Events.RENAME_REQUEST, {
          source: "Collection list",
        });
        return;
      }
      return;
    }
    if (!_newGraphqlName) {
      return;
    }

    const graphqlPayload = {
      name: _newGraphqlName as string,
      description: _graphql?.description as string,
      url: _graphql.graphql?.url as string,
      query: _graphql.graphql?.query,
      schema: _graphql.graphql?.schema,
      headers: _graphql.graphql
        ?.headers as GraphqlRequestKeyValueDtoInterface[],
      auth: _graphql.graphql?.auth as GraphqlRequestAuthDtoInterface,
      variables: _graphql.graphql?.variables,
      selectedGraphqlAuthType: _graphql?.graphql
        ?.selectedGraphqlAuthType as GraphqlRequestAuthModeBaseEnum,
    };

    if (_collection.id && _workspaceId && !_folder.id) {
      const baseUrl = await this.constructBaseUrl(_workspaceId);
      const response = await this.collectionService.updateGraphqlInCollection(
        _graphql.id,
        _collection.id,
        _workspaceId,
        graphqlPayload,
        baseUrl,
      );
      if (!response?.isSuccessful) {
        return;
      }
      this.collectionRepository.updateRequestOrFolderInCollection(
        _collection.id,
        _graphql.id,
        response.data.data,
      );
      this.updateTab(_graphql.id, {
        name: _newGraphqlName,
      });
      MixpanelEvent(Events.RENAME_REQUEST, {
        source: "Collection list",
      });
      return;
    }
    if (_collection.id && _workspaceId && _folder.id) {
      const baseUrl = await this.constructBaseUrl(_workspaceId);
      const response = await this.collectionService.updateGraphqlInCollection(
        _graphql.id,
        _collection.id,
        _workspaceId,
        graphqlPayload,
        baseUrl,
        _folder.id,
      );
      if (!response?.isSuccessful) {
        return;
      }
      this.collectionRepository.updateRequestInFolder(
        _collection.id,
        _folder.id,
        _graphql.id,
        response.data.data,
      );
      this.updateTab(_graphql.id, {
        name: _newGraphqlName,
      });
      MixpanelEvent(Events.RENAME_REQUEST, {
        source: "Collection list",
      });
    }
  };

  /**
   * Handles loading the collection from local repository from active branch
   * @param collection :CollectionDocument
   * @returns :{ activeSyncLoad: boolean; isBranchSynced: boolean }
   */
  public handleBranchSwitch = async (collection: CollectionDto) => {
    const result: { activeSyncLoad: boolean; isBranchSynced: boolean } = {
      activeSyncLoad: true,
      isBranchSynced: true,
    };
    const detectBranch = collection?.currentBranch
      ? collection?.currentBranch
      : collection?.primaryBranch;
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    if (isGuestUser !== true) {
      const response = await this.collectionService.switchCollectionBranch(
        collection.id,
        detectBranch as string,
      );
      await setTimeout(async () => {
        if (response.isSuccessful) {
          await this.collectionRepository.updateCollection(collection.id, {
            currentBranch: detectBranch,
            items: response.data.data.items,
          });
          result.activeSyncLoad = true;
          result.isBranchSynced = true;
        } else {
          await this.collectionRepository.updateCollection(collection.id, {
            currentBranch: detectBranch,
            items: [],
          });
          result.activeSyncLoad = true;
          result.isBranchSynced = false;
        }
      }, 500);
      return result;
    }
  };

  /**
   * Handles deleting a collection
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection going to be deleted
   * @param deletedIds :[string] | [] - the IDs of the collection to be deleted
   */
  private handleDeleteCollection = async (
    workspaceId: string,
    collection: CollectionDto,
    deletedIds: string[] | [],
  ) => {
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      this.collectionRepository.deleteCollection(collection.id);
      this.deleteCollectioninWorkspace(workspaceId, collection.id);

      // Deleting the main and child tabs
      await this.removeTabWithChildren(
        collection.id,
        workspaceId,
        "collection",
      );

      notifications.success(`"${collection.name}" Collection deleted.`);
      MixpanelEvent(Events.DELETE_COLLECTION, {
        source: "Collection list",
      });
      return;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response = await this.collectionService.deleteCollection(
      workspaceId,
      collection.id,
      baseUrl,
    );

    const isMockCollection =
      collection?.collectionType === CollectionTypeBaseEnum.MOCK;

    if (response.isSuccessful) {
      this.collectionRepository.deleteCollection(collection.id);
      this.deleteCollectioninWorkspace(workspaceId, collection.id);

      // Deleting the main and child tabs
      await this.removeTabWithChildren(
        collection.id,
        workspaceId,
        "collection",
      );

      const successMessage = isMockCollection
        ? `'${collection.name}' mock collection deleted successfully.`
        : `"${collection.name}" Collection deleted.`;

      notifications.success(successMessage);
      MixpanelEvent(Events.DELETE_COLLECTION, {
        source: "Collection list",
      });
    } else {
      const errorMessage = isMockCollection
        ? `Failed to delete '${collection.name}'. Please try again.`
        : response.message ?? "Failed to delete collection. Please try again.";
      notifications.error(errorMessage);
    }
  };

  /**
   * Handle deleting folder in a collection
   * @param workspaceId :string
   * @param collection :CollectionDocument - the collection in which the folder is saved
   * @param explorer : - the folder to be deleted
   * @param requestIds : - the request IDs saved inside the folder
   */
  private handleDeleteFolder = async (
    workspaceId: string,
    collection: CollectionDto,
    explorer: CollectionItemsDto,
    requestIds: string[],
  ) => {
    let userSource = {};
    if (collection.activeSync && explorer?.source === "USER") {
      userSource = {
        branchName: collection.currentBranch
          ? collection.currentBranch
          : collection.primaryBranch,
      };
    }
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      this.collectionRepository.deleteRequestOrFolderInCollection(
        collection.id,
        explorer.id,
      );

      // Deleting the main and child tabs
      await this.removeTabWithChildren(explorer.id, workspaceId, "folder");

      notifications.success(`"${explorer.name}" Folder deleted.`);
      MixpanelEvent(Events.DELETE_FOLDER, {
        source: "Collection list",
      });
      return;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response = await this.collectionService.deleteFolderInCollection(
      workspaceId,
      collection.id,
      explorer.id,
      {
        ...userSource,
      },
      baseUrl,
    );

    if (response.isSuccessful) {
      this.collectionRepository.deleteRequestOrFolderInCollection(
        collection.id,
        explorer.id,
      );

      // Deleting the main and child tabs
      await this.removeTabWithChildren(explorer.id, workspaceId, "folder");

      notifications.success(`‘${explorer.name}’ folder deleted successfully.`);
      MixpanelEvent(Events.DELETE_FOLDER, {
        source: "Collection list",
      });
    } else {
      notifications.error("Failed to delete folder. Please try again.");
    }
  };

  /**
   * Handle deleting request from repository as well as backend
   * @param workspaceId :string
   * @param collection :CollectionDocument - The collection in which the request is saved
   * @param request : - The request to be deleted
   * @param folder : - The folder in which the request is saved(if is saved in a folder)
   * @returns :void
   */
  private handleDeleteRequest = async (
    workspaceId: string,
    collection: CollectionDto,
    request: CollectionItemsDto,
    folder: CollectionItemsDto,
  ): Promise<boolean> => {
    let userSource = {};
    if (collection.activeSync) {
      userSource = {
        currentBranch: collection.currentBranch,
      };
    }

    let requestObject = {
      collectionId: collection.id,
      workspaceId: workspaceId,
      folderId: "",
      ...userSource,
    };

    if (folder && collection.id && workspaceId) {
      requestObject = {
        ...requestObject,
        folderId: folder.id,
      };
    }
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      if (folder) {
        await this.collectionRepository.deleteRequestInFolder(
          collection.id,
          folder.id,
          request.id,
        );
        this.tabRepository.removeTab(request.id);
      } else {
        await this.collectionRepository.deleteRequestOrFolderInCollection(
          collection.id,
          request.id,
        );
        this.tabRepository.removeTab(request.id);
      }

      return true;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response = await this.collectionService.deleteRequestInCollection(
      request.id,
      requestObject,
      baseUrl,
    );

    const isMockCollection =
      response.data.data?.collectionType === CollectionTypeBaseEnum.MOCK;
    if (response.isSuccessful) {
      if (
        requestObject.folderId &&
        requestObject.collectionId &&
        requestObject.workspaceId
      ) {
        await this.collectionRepository.deleteRequestInFolder(
          requestObject.collectionId,
          requestObject.folderId,
          request.id,
        );
      } else if (requestObject.workspaceId && requestObject.collectionId) {
        await this.collectionRepository.deleteRequestOrFolderInCollection(
          requestObject.collectionId,
          request.id,
        );
      }

      // Deleting the main and child tabs
      await this.removeTabWithChildren(request.id, workspaceId, "request");

      const successMessage = isMockCollection
        ? `'${request.name}' mock request deleted successfully.`
        : `"${request.name}" Request deleted.`;

      notifications.success(successMessage);
      MixpanelEvent(Events.DELETE_REQUEST, {
        source: "Collection list",
      });
      return true;
    } else {
      const errorMessage = isMockCollection
        ? `Failed to delete '${request.name}'. Please try again.`
        : "Failed to delete API request. Please try again.";

      notifications.error(errorMessage);
      return false;
    }
  };

  /**
   * Handle deleting request from repository as well as backend
   * @param workspaceId :string
   * @param collection :CollectionDocument - The collection in which the AI Request is saved
   * @param aiRequest : - The AI Request to be deleted
   * @param folder : - The folder in which the AI Request is saved(if is saved in a folder)
   * @returns :void
   */
  private handleDeleteAiRequest = async (
    workspaceId: string,
    collection: CollectionDto,
    aiRequest: CollectionItemsDto,
    folder: CollectionItemsDto,
  ): Promise<boolean> => {
    let userSource = {};
    if (collection.activeSync) {
      userSource = {
        currentBranch: collection.currentBranch,
      };
    }

    let aiRequestObject = {
      collectionId: collection.id,
      workspaceId: workspaceId,
      folderId: "",
      ...userSource,
    };

    if (folder && collection.id && workspaceId) {
      aiRequestObject = {
        ...aiRequestObject,
        folderId: folder.id,
      };
    }
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      if (folder) {
        await this.collectionRepository.deleteRequestInFolder(
          collection.id,
          folder.id,
          aiRequest.id,
        );
        this.handleRemoveTab(aiRequest.id);
      } else {
        await this.collectionRepository.deleteRequestOrFolderInCollection(
          collection.id,
          aiRequest.id,
        );
        this.handleRemoveTab(aiRequest.id);
      }

      return true;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response = await this.collectionService.deleteAiRequestInCollection(
      aiRequest.id,
      aiRequestObject,
      baseUrl,
    );

    if (response.isSuccessful) {
      if (
        aiRequestObject.folderId &&
        aiRequestObject.collectionId &&
        aiRequestObject.workspaceId
      ) {
        await this.collectionRepository.deleteRequestInFolder(
          aiRequestObject.collectionId,
          aiRequestObject.folderId,
          aiRequest.id,
        );
      } else if (aiRequestObject.workspaceId && aiRequestObject.collectionId) {
        await this.collectionRepository.deleteRequestOrFolderInCollection(
          aiRequestObject.collectionId,
          aiRequest.id,
        );
      }

      // Deleting the main tab no child exists
      this.handleRemoveTab(aiRequest.id);

      notifications.success(`"${aiRequest.name}" AI request deleted.`);
      // MixpanelEvent(Events.DELETE_REQUEST, {
      //   source: "Collection list",
      // });
      return true;
    } else {
      notifications.error("Failed to delete AI request. Please try again.");
      return false;
    }
  };

  /**
   * Handle deleting request from repository as well as backend
   * @param workspaceId :string
   * @param collection :CollectionDocument - The collection in which the request is saved
   * @param request : - The request to be deleted
   * @param folder : - The folder in which the request is saved(if is saved in a folder)
   * @returns :void
   */
  private handleDeleteSavedRequest = async (
    workspaceId: string,
    collection: CollectionDto,
    request: CollectionItemsDto,
    folder: CollectionItemsDto,
    requestResponse: CollectionItemsDto,
  ): Promise<boolean> => {
    let userSource = {};
    if (collection.activeSync) {
      userSource = {
        currentBranch: collection.currentBranch,
      };
    }

    let requestObject = {
      collectionId: collection.id,
      workspaceId: workspaceId,
      requestId: request.id,
      folderId: "",
      ...userSource,
    };

    if (folder && collection.id && workspaceId) {
      requestObject = {
        ...requestObject,
        folderId: folder.id,
      };
    }
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      if (folder) {
        await this.collectionRepository.deleteSavedRequestInFolder(
          requestObject.collectionId,
          requestObject.folderId,
          request.id,
          requestResponse.id,
        );
        this.tabRepository.removeTab(requestResponse.id);
      } else {
        await this.collectionRepository.deleteSavedRequestInCollection(
          requestObject.collectionId,
          request.id,
          requestResponse.id,
        );
        this.tabRepository.removeTab(requestResponse.id);
      }
      notifications.success(`"${requestResponse.name}" Response deleted.`);
      return true;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response =
      await this.collectionService.deleteSavedRequestInCollection(
        requestResponse.id,
        requestObject,
        baseUrl,
      );

    if (response.isSuccessful) {
      if (
        requestObject.folderId &&
        requestObject.collectionId &&
        requestObject.workspaceId
      ) {
        await this.collectionRepository.deleteSavedRequestInFolder(
          requestObject.collectionId,
          requestObject.folderId,
          request.id,
          requestResponse.id,
        );
      } else if (requestObject.workspaceId && requestObject.collectionId) {
        await this.collectionRepository.deleteSavedRequestInCollection(
          requestObject.collectionId,
          request.id,
          requestResponse.id,
        );
      }

      // Deleting the main tab no child exists
      this.handleRemoveTab(requestResponse.id);

      notifications.success(`"${requestResponse.name}" Response deleted.`);

      MixpanelEvent(Events.DELETE_RESPONSE, {
        source: "Collection list",
      });
      return true;
    } else {
      notifications.error("Failed to delete saved response. Please try again.");
      return false;
    }
  };

  /**
   * Handle deleting request from repository as well as backend
   * @param workspaceId :string
   * @param collection :CollectionDocument - The collection in which the request is saved
   * @param request : - The request to be deleted
   * @param folder : - The folder in which the request is saved(if is saved in a folder)
   * @returns :void
   */
  private handleDeleteWebSocket = async (
    workspaceId: string,
    collection: CollectionDto,
    websocket: CollectionItemsDto,
    folder: CollectionItemsDto,
  ): Promise<boolean> => {
    let userSource = {};
    if (collection.activeSync) {
      userSource = {
        currentBranch: collection.currentBranch,
      };
    }

    let requestObject = {
      collectionId: collection.id,
      workspaceId: workspaceId,
      folderId: "",
      ...userSource,
    };

    if (folder && collection.id && workspaceId) {
      requestObject = {
        ...requestObject,
        folderId: folder.id,
      };
    }
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      if (folder) {
        await this.collectionRepository.deleteRequestInFolder(
          collection.id,
          folder.id,
          websocket.id,
        );
        this.handleRemoveTab(websocket.id);
      } else {
        await this.collectionRepository.deleteRequestOrFolderInCollection(
          collection.id,
          websocket.id,
        );
        this.handleRemoveTab(websocket.id);
      }

      return true;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response = await this.collectionService.deleteSocketInCollection(
      websocket.id,
      requestObject,
      baseUrl,
    );

    if (response.isSuccessful) {
      if (
        requestObject.folderId &&
        requestObject.collectionId &&
        requestObject.workspaceId
      ) {
        await this.collectionRepository.deleteRequestInFolder(
          requestObject.collectionId,
          requestObject.folderId,
          websocket.id,
        );
      } else if (requestObject.workspaceId && requestObject.collectionId) {
        await this.collectionRepository.deleteRequestOrFolderInCollection(
          requestObject.collectionId,
          websocket.id,
        );
      }

      // Deleting the main tab no child exists
      this.handleRemoveTab(websocket.id);

      notifications.success(`"${websocket.name}" WebSocket deleted.`);
      MixpanelEvent(Events.DELETE_REQUEST, {
        source: "Collection list",
      });
      return true;
    } else {
      notifications.error("Failed to delete WebSocket. Please try again.");
      return false;
    }
  };

  /**
   * Handle deleting request from repository as well as backend
   * @param _workspaceId :string
   * @param _collection :CollectionDocument - The collection in which the request is saved
   * @param _socketIo : - The request to be deleted
   * @param _folder : - The folder in which the request is saved(if is saved in a folder)
   * @returns :void
   */
  private handleDeleteSocketIO = async (
    _workspaceId: string,
    _collection: CollectionDto,
    _socketIo: CollectionItemsDto,
    _folder: CollectionItemsDto,
  ): Promise<boolean> => {
    let userSource = {};
    if (_collection.activeSync) {
      userSource = {
        currentBranch: _collection.currentBranch,
      };
    }

    let isGuestUser = true;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      if (_folder) {
        await this.collectionRepository.deleteRequestInFolder(
          _collection.id,
          _folder.id,
          _socketIo.id,
        );
        this.handleRemoveTab(_socketIo.id);
      } else {
        await this.collectionRepository.deleteRequestOrFolderInCollection(
          _collection.id,
          _socketIo.id,
        );
        this.handleRemoveTab(_socketIo.id);
      }

      return true;
    }
    const baseUrl = await this.constructBaseUrl(_workspaceId);
    const response = await this.collectionService.deleteSocketIoInCollection(
      _socketIo.id,
      {
        collectionId: _collection.id,
        workspaceId: _workspaceId,
        folderId: _folder?.id ? _folder?.id : undefined,
        source: _collection.activeSync ? _socketIo?.source : undefined,
        currentBranch: _collection.activeSync
          ? _collection.currentBranch
          : undefined,
      } as SocketIORequestDeletePayloadDtoInterface,
      baseUrl,
    );

    if (!response?.isSuccessful) {
      notifications.error(
        `Failed to delete ${SocketIORequestDefaultAliasBaseEnum.NAME}. Please try again.`,
      );
      return false;
    }
    if (_folder?.id && _collection.id && _workspaceId) {
      await this.collectionRepository.deleteRequestInFolder(
        _collection.id,
        _folder.id,
        _socketIo.id,
      );
    } else if (_workspaceId && _collection.id) {
      await this.collectionRepository.deleteRequestOrFolderInCollection(
        _collection.id,
        _socketIo.id,
      );
    }

    // Deleting the main tab no child exists
    this.handleRemoveTab(_socketIo.id);

    notifications.success(
      `"${_socketIo.name}" ${SocketIORequestDefaultAliasBaseEnum.NAME} deleted.`,
    );
    MixpanelEvent(Events.DELETE_REQUEST, {
      source: "Collection list",
    });
    return true;
  };

  /**
   * Handle deleting GraphQL request from repository as well as backend
   * @param _workspaceId
   * @param _collection The collection in which the GraphQL request is saved
   * @param _graphql  The GraphQL request to be deleted
   * @param _folder The folder in which the GraphQL request is saved (if is saved in a folder)
   * @returns
   */
  private handleDeleteGraphql = async (
    _workspaceId: string,
    _collection: CollectionDto,
    _graphql: CollectionItemsDto,
    _folder: CollectionItemsDto,
  ): Promise<boolean> => {
    let userSource = {};
    if (_collection.activeSync) {
      userSource = {
        currentBranch: _collection.currentBranch,
      };
    }

    let isGuestUser = true;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      if (_folder) {
        await this.collectionRepository.deleteRequestInFolder(
          _collection.id,
          _folder.id,
          _graphql.id,
        );
        this.handleRemoveTab(_graphql.id);
      } else {
        await this.collectionRepository.deleteRequestOrFolderInCollection(
          _collection.id,
          _graphql.id,
        );
        this.handleRemoveTab(_graphql.id);
      }

      return true;
    }
    const baseUrl = await this.constructBaseUrl(_workspaceId);
    const response = await this.collectionService.deleteGraphqlInCollection(
      _graphql.id,
      {
        collectionId: _collection.id,
        workspaceId: _workspaceId,
        folderId: _folder?.id ? _folder?.id : undefined,
        source: _collection.activeSync ? _graphql?.source : undefined,
        currentBranch: _collection.activeSync
          ? _collection.currentBranch
          : undefined,
      } as GraphqlRequestDeletePayloadDtoInterface,
      baseUrl,
    );

    if (!response?.isSuccessful) {
      notifications.error(
        `Failed to delete ${GraphqlRequestDefaultAliasBaseEnum.NAME}. Please try again.`,
      );
      return false;
    }
    if (_folder?.id && _collection.id && _workspaceId) {
      await this.collectionRepository.deleteRequestInFolder(
        _collection.id,
        _folder.id,
        _graphql.id,
      );
    } else if (_workspaceId && _collection.id) {
      await this.collectionRepository.deleteRequestOrFolderInCollection(
        _collection.id,
        _graphql.id,
      );
    }

    // Deleting the main tab no child exists
    this.handleRemoveTab(_graphql.id);

    notifications.success(
      `"${_graphql.name}" ${GraphqlRequestDefaultAliasBaseEnum.NAME} deleted.`,
    );
    MixpanelEvent(Events.DELETE_REQUEST, {
      source: "Collection list",
    });
    return true;
  };

  /**
   * Handle refetching collection from local repository in active sync enabled collections
   * @param workspaceId :string - the workspace ID
   * @param collection :CollectionDocument - The collection going to be refetched
   */
  public handleRefetchCollection = async (
    workspaceId: string,
    collection: CollectionDto,
  ) => {
    const errMessage = `Failed to sync the collection. Local reposisitory branch is not set to ${collection?.currentBranch}.`;

    try {
      const activeResponse = await invoke("get_git_active_branch", {
        path: collection?.localRepositoryPath,
      });
      if (activeResponse) {
        const currentBranch = activeResponse;
        if (collection?.currentBranch) {
          if (currentBranch !== collection?.currentBranch) {
            notifications.error(errMessage);
            return;
          }
        } else {
          if (currentBranch !== collection?.primaryBranch) {
            notifications.error(errMessage);
            return;
          }
        }
      } else {
        notifications.error(errMessage);
        return;
      }
    } catch (e) {
      notifications.error(errMessage);
      return;
    }
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    if (isGuestUser !== true) {
      const responseJSON =
        (await this.collectionService.validateImportCollectionURL(
          collection.activeSyncUrl,
        )) as {
          data: {
            headers: string;
            response: string;
            status: string;
          };
        };
      const dt = {
        url: collection.activeSyncUrl as string,
        urlData: {
          data: JSON.parse(responseJSON.data.response) as string,
          headers: responseJSON.data.headers as string,
        },
        primaryBranch: collection?.primaryBranch as string,
        currentBranch: collection?.currentBranch
          ? (collection?.currentBranch as string)
          : (collection?.primaryBranch as string),
      };
      if (responseJSON?.data?.status === ResponseStatusCode.OK) {
        const response = await this.collectionService.importCollection(
          workspaceId,
          dt,
          collection.activeSync,
        );

        if (response.isSuccessful) {
          this.collectionRepository.updateCollection(
            collection.id,
            response.data.data.collection,
          );
          notifications.success("Collection synced successfully.");
        } else {
          notifications.error(
            "Failed to sync the collection. Please try again.",
          );
        }
      } else {
        notifications.error(
          `Unable to detect ${collection?.activeSyncUrl?.replace(
            "-json",
            "",
          )}.`,
        );
      }
    }
  };

  /**
   *
   * @param collectionId - collection id
   * @param items - request or folder item
   */
  public addRequestOrFolderInCollection = (
    collectionId: string,
    items: object,
  ) => {
    this.collectionRepository.addRequestOrFolderInCollection(
      collectionId,
      items,
    );
  };

  /**
   *
   * @param _workspaceMeta - workspace meta data
   * @param _collectionId - collection id
   * @param _folderName - folder name
   * @returns - folder status message
   */
  public createFolderFromSaveAs = async (
    _workspaceMeta: {
      id: string;
      name: string;
    },
    _collectionId: string,
    _folderName: string,
  ) => {
    let userSource = {};
    const _collection: CollectionDocument =
      await this.readCollection(_collectionId);
    if (_collection?.activeSync) {
      userSource = {
        currentBranch: _collection?.currentBranch,
        source: "USER",
      };
    }

    const directory: CreateDirectoryPostBody = {
      name: _folderName,
      description: "",
      ...userSource,
    };

    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      const data = {
        id: uuidv4(),
        name: _folderName,
        description: "",
        type: "FOLDER",
        source: "USER",
        isDeleted: false,
        items: [],
        createdBy: "Guest User",
        updatedBy: "Guest User",
        createdAt: "",
        updatedAt: "",
      };

      const latestRoute = {
        id: data.id,
      };
      return {
        status: "success",
        data: {
          latestRoute,
          collectionId: _collectionId,
          data: data,
          addRequestOrFolderInCollection: this.addRequestOrFolderInCollection,
        },
      };
    }

    const res = await insertCollectionDirectory(
      _workspaceMeta.id,
      _collectionId,
      directory,
    );
    if (res.isSuccessful) {
      const latestRoute = {
        id: res.data.data.id,
      };
      return {
        status: "success",
        data: {
          latestRoute,
          collectionId: _collectionId,
          data: res.data.data,
          addRequestOrFolderInCollection: this.addRequestOrFolderInCollection,
        },
      };
    } else {
      return {
        status: "error",
        message: res.message,
      };
    }
  };

  /**
   *
   * @param _workspaceMeta - workspace meta data
   * @param _collectionName - collection name
   * @returns - collection status message
   */
  public createCollectionFromSaveAs = async (
    _workspaceMeta: {
      id: string;
      name: string;
    },
    _collectionName: string,
  ) => {
    const newCollection = {
      name: _collectionName,
      workspaceId: _workspaceMeta.id,
    };

    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    if (isGuestUser === true) {
      const data: {
        id?: string;
        name: string;
        totalRequests: number;
        createdBy: string;
        items?: CollectionItemsDto[];
        updatedBy: string;
        createdAt: string;
        updatedAt: string;
        workspaceId?: string;
      } = {
        id: uuidv4(),
        name: _collectionName,
        totalRequests: 0,
        items: [],
        // createdAt: new Date().toISOString,
        createdAt: "",
        createdBy: "Guest User",
        // updatedAt: new Date().toISOString,
        updatedAt: "",
        updatedBy: "Guest User",
      };
      const latestRoute = {
        id: data.id,
      };
      const storage = data;

      storage.workspaceId = _workspaceMeta.id;
      MixpanelEvent(Events.CREATE_COLLECTION, {
        source: "SaveRequest",
        collectionName: data.name,
        collectionId: data.id,
      });
      return {
        status: "success",
        data: {
          latestRoute,
          storage,
          addCollection: this.addCollection,
        },
      };
    }
    const res = await insertCollection(newCollection);
    if (res.isSuccessful) {
      const latestRoute = {
        id: res.data.data._id,
      };
      const storage = res.data.data;
      const _id = res.data.data._id;
      delete storage._id;
      storage.id = _id;
      storage.workspaceId = _workspaceMeta.id;
      MixpanelEvent(Events.CREATE_COLLECTION, {
        source: "SaveRequest",
        collectionName: res.data.data.name,
        collectionId: res.data.data._id,
      });
      return {
        status: "success",
        data: {
          latestRoute,
          storage,
          addCollection: this.addCollection,
        },
      };
    } else {
      return {
        status: "error",
        message: res.message,
      };
    }
  };

  /**
   *
   * @param _workspaceMeta - workspace meta data
   * @param path - request stack path
   * @param tabName - request name
   * @param description - request description
   * @param type - save over all request or description only
   * @param componentData - tab data
   */
  public saveAsRequest = async (
    _workspaceMeta: {
      id: string;
      name: string;
    },
    path: {
      name: string;
      id: string;
      type: string;
    }[],
    tabName: string,
    description: string,
    componentData: Tab,
  ) => {
    let userSource = {};
    if (path.length > 0) {
      const requestTabAdapter = new RequestTabAdapter();
      const unadaptedRequest = requestTabAdapter.unadapt(componentData);
      const req = {
        id: uuidv4(),
        name: tabName,
        description,
        type: ItemType.REQUEST,
        request: unadaptedRequest,
        source: "USER",
        isDeleted: false,
        createdBy: "Guest User",
        updatedBy: "Guest User",
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
      };
      if (path[path.length - 1].type === ItemType.COLLECTION) {
        /**
         * handle request at collection level
         */
        const _collection = await this.readCollection(path[path.length - 1].id);
        if (_collection?.activeSync) {
          userSource = {
            currentBranch: _collection?.currentBranch,
            source: "USER",
          };
        }
        let isGuestUser;
        isGuestUserActive.subscribe((value) => {
          isGuestUser = value;
        });

        if (isGuestUser === true) {
          this.addRequestOrFolderInCollection(path[path.length - 1].id, req);
          return {
            status: "success",
            message: "",
            data: {
              id: req.id,
            },
          };
        }
        const baseUrl = await this.constructBaseUrl(_workspaceMeta.id);
        const res = await insertCollectionRequest(
          {
            collectionId: path[path.length - 1].id,
            workspaceId: _workspaceMeta.id,
            ...userSource,
            items: {
              name: tabName,
              description,
              type: ItemType.REQUEST,
              request: unadaptedRequest,
            },
          },
          baseUrl,
        );
        if (res.isSuccessful) {
          this.addRequestOrFolderInCollection(
            path[path.length - 1].id,
            res.data.data,
          );
          return {
            status: "success",
            message: res.message,
            data: {
              id: res.data.data.id,
            },
          };
        } else {
          return {
            status: "error",
            message: res.message,
          };
        }
      } else if (path[path.length - 1].type === ItemType.FOLDER) {
        /**
         * handle request at folder level
         */
        const _collection = await this.readCollection(path[0].id);
        if (_collection?.activeSync) {
          userSource = {
            currentBranch: _collection?.currentBranch,
            source: "USER",
          };
        }
        let isGuestUser;
        isGuestUserActive.subscribe((value) => {
          isGuestUser = value;
        });

        if (isGuestUser === true) {
          this.collectionRepository.addRequestInFolder(
            path[0].id,
            path[path.length - 1].id,
            req,
          );
          return {
            status: "success",
            message: "",
            data: {
              id: req.id,
            },
          };
        }
        const baseUrl = await this.constructBaseUrl(_workspaceMeta.id);
        const res = await insertCollectionRequest(
          {
            collectionId: path[0].id,
            workspaceId: _workspaceMeta.id,
            folderId: path[path.length - 1].id,
            ...userSource,
            items: {
              name: path[path.length - 1].name,
              type: ItemType.FOLDER,
              items: {
                name: tabName,
                description,
                type: ItemType.REQUEST,
                request: unadaptedRequest,
              },
            },
          },
          baseUrl,
        );
        if (res.isSuccessful) {
          this.collectionRepository.addRequestInFolder(
            path[0].id,
            path[path.length - 1].id,
            res.data.data,
          );
          return {
            status: "success",
            message: res.message,
            data: {
              id: res.data.data.id,
            },
          };
        } else {
          return {
            status: "error",
            message: res.message,
          };
        }
      }
      MixpanelEvent(Events.SAVE_API_REQUEST);
    }
  };

  /**
   * Handle control of moving items
   * @param args :object - arguments depending on entity type
   */

  public handleMoveItem = async (args: MoveRequestArgsDto) => {
    return await this.handleMoveRequest(
      args.oldCollectionId,
      args.newCollectionId,
      args.oldFolderId,
      args.newFolderId,
      args.requestId,
      args.targetRequestId,
      args.insertPosition,
    );
  };

  /**
   * Handle control of creating items
   * @param entityType :string - type of entity, collection, folder or request
   * @param args :object - arguments depending on entity type
   */
  public handleCreateItem = async (
    entityType: string,
    args: CollectionArgsDto,
  ) => {
    let response;
    switch (entityType) {
      case "collection":
        response = await this.handleCreateCollection(args.workspaceId);
        break;
      case "mockCollection":
        response = await this.handleCreateMockCollection(args.workspaceId);
        break;
      case "folder":
        await this.handleCreateFolderInCollection(
          args.workspaceId,
          args.collection as CollectionDto,
        );
        break;
      case "request":
        await this.createNewTab();
        break;
      case "requestCollection":
        await this.handleCreateRequestInCollection(
          args.workspaceId,
          args.collection as CollectionDto,
        );
        break;
      case "mockRequestCollection":
        await this.handleCreateMockRequestInCollection(
          args.workspaceId,
          args.collection as CollectionDto,
        );
        break;
      case "requestFolder":
        await this.handleCreateRequestInFolder(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
        );
        break;
      case "requestMockFolder":
        await this.handleCreateMockRequestInFolder(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
        );
        break;
      case "web-socket":
        await this.createWebSocketNewTab();
        break;
      case "websocketCollection":
        await this.handleCreateWebSocketInCollection(
          args.workspaceId,
          args.collection as CollectionDto,
        );
        break;
      case "websocketFolder":
        await this.handleCreateWebSocketInFolder(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
        );
        break;
      case "socket-io":
        await this.createSocketIoNewTab();
        break;
      case "socketioCollection":
        await this.handleCreateSocketIoInCollection(
          args.workspaceId,
          args.collection as CollectionDto,
        );
        break;
      case "socketioFolder":
        await this.handleCreateSocketIoInFolder(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
        );
        break;
      case "graphql":
        await this.createGraphqlNewTab();
        break;
      case "graphqlCollection":
        await this.handleCreateGraphqlInCollection(
          args.workspaceId,
          args.collection as CollectionDto,
        );
        break;
      case "graphqlFolder":
        await this.handleCreateGraphqlInFolder(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
        );
        break;
      case "aiRequest":
        await this.createAiRequestNewTab();
        break;
      case "aiRequestCollection":
        await this.handleCreateAiRequestInCollection(
          args.workspaceId,
          args.collection as CollectionDto,
        );
        break;
      case "aiRequestFolder":
        await this.handleCreateAiRequestInFolder(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
        );
        break;
    }
    return response;
  };

  /**
   * Handle control of deleting item
   * @param entityType :srting - type of entity, collection, folder or request
   * @param args :object - arguments depending on entity type
   */
  public handleDeleteItem = async (
    entityType: string,
    args: CollectionArgsDto,
  ) => {
    switch (entityType) {
      case "collection":
        this.handleDeleteCollection(
          args.workspaceId,
          args.collection as CollectionDto,
          args.deletedIds as string[],
        );
        break;
      case "folder":
        this.handleDeleteFolder(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.requestIds as string[],
        );
        break;
      case "request":
        this.handleDeleteRequest(
          args.workspaceId,
          args.collection as CollectionDto,
          args.request as CollectionItemsDto,
          args.folder as CollectionItemsDto,
        );
        break;
      case "aiRequest":
        this.handleDeleteAiRequest(
          args.workspaceId,
          args.collection as CollectionDto,
          args.aiRequest as CollectionItemsDto,
          args.folder as CollectionItemsDto,
        );
        break;
      case "websocket":
        this.handleDeleteWebSocket(
          args.workspaceId,
          args.collection as CollectionDto,
          args.websocket as CollectionItemsDto,
          args.folder as CollectionItemsDto,
        );
        break;
      case "socket-io":
        this.handleDeleteSocketIO(
          args.workspaceId,
          args.collection as CollectionDto,
          args.socketio as CollectionItemsDto,
          args.folder as CollectionItemsDto,
        );
        break;
      case "graphql":
        this.handleDeleteGraphql(
          args.workspaceId,
          args.collection as CollectionDto,
          args.graphql as CollectionItemsDto,
          args.folder as CollectionItemsDto,
        );
        break;
      case "saved_request":
        this.handleDeleteSavedRequest(
          args.workspaceId,
          args.collection as CollectionDto,
          args.request as CollectionItemsDto,
          args.folder as CollectionItemsDto,
          args.requestResponse as CollectionItemsDto,
        );
        break;
    }
  };

  /**
   * Handle control of Renaming items
   * @param entityType :string - type of entity, collection, folder or request
   * @param args :object - arguments depending on entity type
   */
  public handleRenameItem = async (
    entityType: string,
    args: CollectionArgsDto,
  ) => {
    switch (entityType) {
      case "collection":
        this.handleRenameCollection(
          args.workspaceId,
          args.collection as CollectionDto,
          args.newName as string,
        );
        break;
      case "folder":
        this.handleRenameFolder(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.newName as string,
        );
        break;
      case "request":
        this.handleRenameRequest(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.request as CollectionItemsDto,
          args.newName as string,
        );
        break;
      case "mockRequest":
        this.handleRenameMockRequest(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.request as CollectionItemsDto,
          args.newName as string,
        );
        break;
      case "aiRequest":
        this.handleRenameAiRequest(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.aiRequest as CollectionItemsDto,
          args.newName as string,
        );
        break;
      case "web-socket":
        this.handleRenameWebSocket(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.websocket as CollectionItemsDto,
          args.newName as string,
        );
        break;
      case "socket-io":
        this.handleRenameSocketIO(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.socketio as CollectionItemsDto,
          args.newName as string,
        );
        break;
      case "graphql":
        this.handleRenameGraphql(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.graphql as CollectionItemsDto,
          args.newName as string,
        );
        break;
      case "saved_request":
        this.handleRenameSavedRequest(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.request as CollectionItemsDto,
          args.requestResponse as CollectionItemsDto,
          args.newName as string,
        );
        break;
    }
  };

  /**
   * Handle control of Import items
   * @param entityType :string - type of entity, collection, folder or request
   * @param args :object - arguments depending on entity type
   */
  public handleImportItem = (entityType: string, args: CollectionArgsDto) => {
    switch (entityType) {
      case "curl":
        this.handleImportCurl(args.workspaceId, args.parsedCurlData);
        break;
    }
  };

  public handleOpenItem = async (entitytype: string, args: any) => {
    switch (entitytype) {
      case "collection":
        this.handleOpenCollection(
          args.workspaceId,
          args.collection as CollectionDto,
          args?.navigation,
        );
        break;
      case "folder":
        this.handleOpenFolder(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
        );
        break;
      case "request":
        this.handleOpenRequest(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.request as CollectionItemsDto,
        );
        break;
      case "mockRequest":
        this.handleOpenMockRequest(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.request as CollectionItemsDto,
        );
        break;
      case "aiRequest":
        this.handleOpenAiRequest(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.aiRequest as CollectionItemsDto,
        );
        break;
      case "saved_request":
        this.handleOpenSavedRequest(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.request as CollectionItemsDto,
          args.savedRequest as CollectionItemsDto,
        );
        break;
      case "websocket":
        this.handleOpenWebSocket(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.websocket as CollectionItemsDto,
        );
        break;
      case "socket-io":
        this.handleOpenSocketIoTab(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.socketio as CollectionItemsDto,
        );
        break;
      case "graphql":
        this.handleOpenGraphqlTab(
          args.workspaceId,
          args.collection as CollectionDto,
          args.folder as CollectionItemsDto,
          args.graphql as CollectionItemsDto,
        );
        break;
      case "mockHistory":
        this.handleOpenMockHistory(
          args.workspaceId,
          args.collection as CollectionDto,
        );
        break;
    }
  };

  public handleOnChangeViewInRequest = async (view: string) => {
    tabsSplitterDirection.set(view);
  };

  public importJSONObject = async (
    currentWorkspaceId: string,
    importJSON: string,
    contentType: ContentTypeEnum,
    activeSyncEnabled: boolean,
    activeSyncUrl: string,
  ) => {
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    if (isGuestUser !== true) {
      let oapiJSON = importJSON;
      if (contentType === ContentTypeEnum["application/json"]) {
        oapiJSON = {
          ...JSON.parse(importJSON),
          isActiveSyncEnabled: activeSyncEnabled,
          activeSyncUrl: activeSyncEnabled ? activeSyncUrl : "",
        };
      }
      const response =
        await this.collectionService.importCollectionFromJsonObject(
          currentWorkspaceId,
          oapiJSON,
          contentType,
        );

      if (response?.isSuccessful) {
        this.collectionRepository.addCollection({
          ...response.data.data,
          id: response.data.data._id,
          workspaceId: currentWorkspaceId,
        });

        const collectionTab = new CollectionTabAdapter().adapt(
          currentWorkspaceId,
          {
            ...response.data.data,
            id: response.data.data._id,
          },
        );

        this.tabRepository.createTab(collectionTab);
        scrollToTab("");

        this.workspaceRepository.updateCollectionInWorkspace(
          currentWorkspaceId,
          {
            id: response.data.data._id,
            name: response.data.data.name,
          },
        );
        MixpanelEvent(Events.IMPORT_COLLECTION, {
          collectionName: response.data.data.name,
          collectionId: response.data.data._id,
          importThrough: "ByObject",
        });
        notifications.success("Collection imported successfully.");
      } else {
        notifications.error("Failed to import collection. Please try again.");
      }
      return response;
    }
  };

  public collectionFileUpload = async (
    currentWorkspaceId: string,
    file: File,
    type: string,
  ) => {
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    if (isGuestUser !== true) {
      let response;
      if (type === "POSTMAN") {
        response = await this.collectionService.importCollectionFromPostmanFile(
          currentWorkspaceId,
          file,
        );
      } else {
        response = await this.collectionService.importCollectionFromFile(
          currentWorkspaceId,
          file,
        );
      }
      if (response?.isSuccessful) {
        this.collectionRepository.addCollection({
          ...response.data.data,
          id: response.data.data._id,
          workspaceId: currentWorkspaceId,
        });

        const collectionTab = new CollectionTabAdapter().adapt(
          currentWorkspaceId,
          {
            ...response.data.data,
            id: response.data.data._id,
          },
        );

        this.tabRepository.createTab(collectionTab);
        scrollToTab("");

        this.workspaceRepository.updateCollectionInWorkspace(
          currentWorkspaceId,
          {
            id: response.data.data._id,
            name: response.data.data.name,
          },
        );
        notifications.success("Collection imported successfully.");
        MixpanelEvent(Events.IMPORT_COLLECTION, {
          collectionName: response.data.data.name,
          collectionId: response.data.data._id,
          importThrough: "ByFile",
        });
      } else {
        notifications.error("Failed to import collection. Please try again.");
      }
      return response;
    }
  };

  public importPostmanCollection = async (
    currentWorkspaceId: string,
    postmanCollectionJson: string,
  ) => {
    // Create a Blob from the JSON string
    const blob = new Blob([postmanCollectionJson], {
      type: "application/json",
    });
    // Create a File object (filename can be anything, e.g., "collection.json")
    const file = new File([blob], "collection.json", {
      type: "application/json",
    });

    return await this.collectionFileUpload(currentWorkspaceId, file, "POSTMAN");
  };

  public importCollectionURL = async (
    currentWorkspaceId: string,
    requestBody: ImportBodyUrl,
    activeSync: boolean,
  ) => {
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    if (isGuestUser !== true) {
      const response = await this.collectionService.importCollection(
        currentWorkspaceId,
        requestBody,
        activeSync,
      );

      if (response?.isSuccessful) {
        const collectionTab = new CollectionTabAdapter().adapt(
          currentWorkspaceId,
          {
            ...response.data.data.collection,
            id: response.data.data.collection._id,
          },
        );

        if (response.data.data.existingCollection) {
          this.collectionRepository.updateCollection(
            response.data.data.collection._id,
            {
              ...response.data.data.collection,
              id: response.data.data.collection._id,
              currentBranch: requestBody.currentBranch,
            },
          );
          notifications.error("Collection already exists.");
        } else {
          this.collectionRepository.addCollection({
            ...response.data.data.collection,
            id: response.data.data.collection._id,
            currentBranch: requestBody.currentBranch,
            workspaceId: currentWorkspaceId,
          });
          this.workspaceRepository.updateCollectionInWorkspace(
            currentWorkspaceId,
            {
              id: response.data.data.collection._id,
              name: response.data.data.collection.name,
            },
          );
          notifications.success("Collection imported successfully.");
        }

        this.tabRepository.createTab(collectionTab);
        scrollToTab("");

        MixpanelEvent(Events.IMPORT_COLLECTION, {
          collectionName: response.data.data.collection.name,
          collectionId: response.data.data.collection._id,
          importThrough: "ByObject",
        });
      } else {
        notifications.error("Failed to import collection. Please try again.");
      }
      return response;
    }
  };

  /**
   * Fetches the collection guide document.
   *
   * @returns - A promise that resolves to the collection guide document.
   */
  public fetchCollectionGuide = async (query: GuideQuery) => {
    const data = await this.guideRepository.findOne(query);
    return data;
  };

  /**
   * Updates the collection guide document's active status.
   *
   * @param isActive - The new active status to set for the collection guide.
   * @returns - A promise that resolves when the update is complete.
   */
  public updateCollectionGuide = async (
    query: GuideQuery,
    isActive: boolean,
  ) => {
    await this.guideRepository.update(query, {
      isActive: isActive,
    });
  };

  /**
   * Handles collection rename
   * @param collection - collction to rename
   * @param newCollectionName :string - the new name of the collection
   */
  public handleSaveAsRenameCollection = async (
    workspaceId: string,
    collectionId: string,
    newCollectionName: string,
  ) => {
    if (newCollectionName) {
      let isGuestUser;
      isGuestUserActive.subscribe((value) => {
        isGuestUser = value;
      });
      if (isGuestUser === true) {
        const colData =
          await this.collectionRepository.readCollection(collectionId);
        const col: CollectionDocType = colData.toMutableJSON();
        col.name = newCollectionName;
        this.collectionRepository.updateCollection(collectionId, col);
        // notifications.success("Collection renamed successfully!");
        return {
          isSuccessful: true,
        };
      }
      const baseUrl = await this.constructBaseUrl(workspaceId);
      const response = await this.collectionService.updateCollectionData(
        collectionId,
        workspaceId,
        { name: newCollectionName },
        baseUrl,
      );
      if (response.isSuccessful) {
        this.collectionRepository.updateCollection(
          collectionId,
          response.data.data,
        );
        notifications.success("Collection renamed successfully!");
      } else if (response.message === "Network Error") {
        notifications.error(response.message);
      } else {
        notifications.error("Failed to rename collection. Please try again.");
      }
      return response;
    }
  };

  /**
   * Handle folder rename
   * @param workspaceId - workspace id of the folder
   * @param collectionId - collection id of the folder
   * @param folderId  - folder id to be targetted
   * @param newFolderName - new folder name
   * @returns
   */
  public handleSaveAsRenameFolder = async (
    workspaceId: string,
    collectionId: string,
    folderId: string,
    newFolderName: string,
  ) => {
    const collection =
      await this.collectionRepository.readCollection(collectionId);
    const explorer =
      await this.collectionRepository.readRequestOrFolderInCollection(
        collectionId,
        folderId,
      );
    if (newFolderName) {
      let userSource = {};
      if (collection.activeSync && explorer?.source === "USER") {
        userSource = {
          currentBranch: collection.currentBranch
            ? collection.currentBranch
            : collection.primaryBranch,
          source: "USER",
        };
      }
      let isGuestUser;
      isGuestUserActive.subscribe((value) => {
        isGuestUser = value;
      });
      if (isGuestUser === true) {
        const res =
          await this.collectionRepository.readRequestOrFolderInCollection(
            collectionId,
            folderId,
          );
        if (res) {
          res.name = newFolderName;
        }

        this.collectionRepository.updateRequestOrFolderInCollection(
          collectionId,
          folderId,
          res,
        );
        // notifications.success("Folder renamed successfully!");
        return {
          isSuccessful: true,
        };
      }
      const baseUrl = await this.constructBaseUrl(workspaceId);
      const response = await this.collectionService.updateFolderInCollection(
        workspaceId,
        collectionId,
        folderId,
        {
          ...userSource,
          name: newFolderName,
        },
        baseUrl,
      );
      if (response.isSuccessful) {
        this.collectionRepository.updateRequestOrFolderInCollection(
          collectionId,
          folderId,
          response.data.data,
        );
        notifications.success("Folder renamed successfully!");
      } else {
        notifications.error("Failed to rename folder. Please try again.");
      }
      return response;
    }
  };

  /**
   * Fetch a specific feature data
   */
  public getFeatureStatus = async (query: FeatureQuery) => {
    return await this.featureSwitchRepository.findOne(query);
  };

  /**
   *
   * @param _workspaceMeta - workspace meta data
   * @param path - request stack path
   * @param tabName - request name
   * @param description - request description
   * @param type - save over all request or description only
   */
  public saveAsSocket = async (
    _workspaceMeta: {
      id: string;
      name: string;
    },
    path: {
      name: string;
      id: string;
      type: string;
    }[],
    tabName: string,
    description: string,
    componentData: Tab,
  ) => {
    let userSource = {};
    // const _id = componentData.id;
    if (path.length > 0) {
      const socketTabAdapter = new SocketTabAdapter();
      const unadaptedSocket = socketTabAdapter.unadapt(componentData);
      const req = {
        id: uuidv4(),
        name: tabName,
        description,
        type: ItemType.WEB_SOCKET,
        websocket: unadaptedSocket,
        source: "USER",
        isDeleted: false,
        createdBy: "Guest User",
        updatedBy: "Guest User",
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
      };
      if (path[path.length - 1].type === ItemType.COLLECTION) {
        /**
         * handle request at collection level
         */
        const _collection = await this.readCollection(path[path.length - 1].id);
        if (_collection?.activeSync) {
          userSource = {
            currentBranch: _collection?.currentBranch,
            source: "USER",
          };
        }
        let isGuestUser;
        isGuestUserActive.subscribe((value) => {
          isGuestUser = value;
        });

        if (isGuestUser == true) {
          this.addRequestOrFolderInCollection(path[path.length - 1].id, req);
          return {
            status: "success",
            message: "success",
            data: {
              id: req.id,
            },
          };
        }
        const baseUrl = await this.constructBaseUrl(_workspaceMeta.id);
        const res = await this.collectionService.addSocketInCollection(
          {
            collectionId: path[path.length - 1].id,
            workspaceId: _workspaceMeta.id,
            ...userSource,
            items: {
              name: tabName,
              description,
              type: ItemType.WEB_SOCKET,
              websocket: unadaptedSocket,
            },
          },
          baseUrl,
        );
        if (res.isSuccessful) {
          this.addRequestOrFolderInCollection(
            path[path.length - 1].id,
            res.data.data,
          );
          return {
            status: "success",
            message: res.message,
            data: {
              id: res.data.data.id,
            },
          };
        } else {
          return {
            status: "error",
            message: res.message,
          };
        }
      } else if (path[path.length - 1].type === ItemType.FOLDER) {
        /**
         * handle request at folder level
         */
        const _collection = await this.readCollection(path[0].id);
        if (_collection?.activeSync) {
          userSource = {
            currentBranch: _collection?.currentBranch,
            source: "USER",
          };
        }
        let isGuestUser;
        isGuestUserActive.subscribe((value) => {
          isGuestUser = value;
        });

        if (isGuestUser == true) {
          this.collectionRepository.addRequestInFolder(
            path[0].id,
            path[path.length - 1].id,
            req,
          );

          return {
            status: "success",
            message: "success",
            data: {
              id: req.id,
            },
          };
        }
        const baseUrl = await this.constructBaseUrl(_workspaceMeta.id);
        const res = await this.collectionService.addSocketInCollection(
          {
            collectionId: path[0].id,
            workspaceId: _workspaceMeta.id,
            folderId: path[path.length - 1].id,
            ...userSource,
            items: {
              id: path[path.length - 1].id,
              name: path[path.length - 1].name,
              type: ItemType.FOLDER,
              items: {
                name: tabName,
                description,
                type: ItemType.WEB_SOCKET,
                websocket: unadaptedSocket,
              },
            },
          },
          baseUrl,
        );
        if (res.isSuccessful) {
          this.collectionRepository.addRequestInFolder(
            path[0].id,
            path[path.length - 1].id,
            res.data.data,
          );

          return {
            status: "success",
            message: res.message,
            data: {
              id: res.data.data.id,
            },
          };
        } else {
          return {
            status: "error",
            message: res.message,
          };
        }
      }
      MixpanelEvent(Events.SAVE_API_REQUEST);
    }
  };

  /**
   * Save Request
   * @param saveDescriptionOnly - refers save overall request data or only description as a documentation purpose.
   * @returns save status
   */
  public saveSocket = async (_componentData: Tab) => {
    const componentData: Tab = _componentData;
    const { folderId, collectionId, workspaceId } = componentData.path;

    if (!workspaceId || !collectionId) {
      return {
        status: "error",
        message: "web socket is not a part of any workspace or collection",
      };
    }
    const _collection = await this.readCollection(collectionId);
    let userSource = {};
    if (_collection?.activeSync && componentData?.source === "USER") {
      userSource = {
        currentBranch: _collection?.currentBranch,
        source: "USER",
      };
    }
    const _id = componentData.id;

    const socketTabAdapter = new SocketTabAdapter();
    const unadaptedSocket = socketTabAdapter.unadapt(componentData);
    // Save overall api

    const socketMetaData = {
      id: _id,
      name: componentData?.name,
      description: componentData?.description,
      type: ItemType.WEB_SOCKET,
    };

    let folderSource;
    let itemSource;
    if (folderId) {
      folderSource = {
        folderId: folderId,
      };
      itemSource = {
        id: folderId,
        type: ItemType.FOLDER,
        items: {
          ...socketMetaData,
          websocket: unadaptedSocket,
        },
      };
    } else {
      itemSource = {
        ...socketMetaData,
        websocket: unadaptedSocket,
      };
    }

    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    if (isGuestUser === true) {
      const progressiveTab = _componentData;
      const data = {
        id: progressiveTab.id,
        name: socketMetaData.name,
        description: socketMetaData.description,
        type: ItemType.WEB_SOCKET,
        websocket: unadaptedSocket,
        updatedAt: "",
        updatedBy: "Guest User",
      };

      // progressiveTab.isSaved = true;
      // this.tab = progressiveTab;
      // await this.tabRepository.updateTab(progressiveTab.tabId, progressiveTab);
      if (!folderId) {
        this.collectionRepository.updateRequestOrFolderInCollection(
          collectionId,
          _id,
          data,
        );
      } else {
        this.collectionRepository.updateRequestInFolder(
          collectionId,
          folderId,
          _id,
          data,
        );
      }
      return {
        status: "success",
        message: "",
      };
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const res = await this.collectionService.updateSocketInCollection(
      _id,
      {
        collectionId: collectionId,
        workspaceId: workspaceId,
        ...folderSource,
        ...userSource,
        items: itemSource,
      },
      baseUrl,
    );

    if (res.isSuccessful) {
      // const progressiveTab = _componentData;
      // progressiveTab.isSaved = true;
      // this.tab = progressiveTab;
      // await this.tabRepository.updateTab(progressiveTab.tabId, progressiveTab);
      if (!folderId) {
        this.collectionRepository.updateRequestOrFolderInCollection(
          collectionId,
          _id,
          res.data.data,
        );
      } else {
        this.collectionRepository.updateRequestInFolder(
          collectionId,
          folderId,
          _id,
          res.data.data,
        );
      }
      return {
        status: "success",
        message: res.message,
      };
    } else {
      return {
        status: "error",
        message: res.message,
      };
    }
  };

  /**
   * Save Request
   * @param saveDescriptionOnly - refers save overall request data or only description as a documentation purpose.
   * @returns save status
   */
  public saveSocketIo = async (componentData: Tab) => {
    const { folderId, collectionId, workspaceId } = componentData.path;

    if (!workspaceId || !collectionId) {
      return {
        status: "error",
        message: "request is not a part of any workspace or collection",
      };
    }
    const _collection = await this.readCollection(collectionId);
    let userSource = {};
    if (_collection?.activeSync && componentData?.source === "USER") {
      userSource = {
        currentBranch: _collection?.currentBranch,
        source: "USER",
      };
    }
    const _id = componentData.id;

    const socketTabAdapter = new SocketIoTabAdapter();
    const unadaptedSocket = socketTabAdapter.unadapt(componentData);
    // Save overall api

    const socketMetaData = {
      id: _id,
      name: componentData?.name,
      description: componentData?.description,
      type: CollectionItemTypeBaseEnum.SOCKETIO,
    };

    let folderSource;
    let itemSource;
    if (folderId) {
      folderSource = {
        folderId: folderId,
      };
      itemSource = {
        id: folderId,
        type: CollectionItemTypeBaseEnum.FOLDER,
        items: {
          ...socketMetaData,
          socketio: unadaptedSocket,
        },
      };
    } else {
      itemSource = {
        ...socketMetaData,
        socketio: unadaptedSocket,
      };
    }

    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    if (isGuestUser === true) {
      const data = {
        id: _id,
        name: socketMetaData.name,
        description: socketMetaData.description,
        type: ItemType.SOCKET_IO,
        socketio: unadaptedSocket,
        updatedAt: "",
        updatedBy: "Guest User",
      };

      if (!folderId) {
        this.collectionRepository.updateRequestOrFolderInCollection(
          collectionId,
          _id,
          data,
        );
      } else {
        this.collectionRepository.updateRequestInFolder(
          collectionId,
          folderId,
          _id,
          data,
        );
      }
      return {
        status: "success",
        message: "",
      };
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const res = await this.collectionService.updateSocketIoInCollection(
      _id,
      {
        collectionId: collectionId,
        workspaceId: workspaceId,
        ...folderSource,
        ...userSource,
        items: itemSource,
      } as
        | SocketIORequestCreateUpdateInCollectionPayloadDtoInterface
        | SocketIORequestCreateUpdateInFolderPayloadDtoInterface,
      baseUrl,
    );

    if (res.isSuccessful) {
      if (!folderId) {
        this.collectionRepository.updateRequestOrFolderInCollection(
          collectionId,
          _id,
          res.data.data,
        );
      } else {
        this.collectionRepository.updateRequestInFolder(
          collectionId,
          folderId,
          _id,
          res.data.data,
        );
      }
      return {
        status: "success",
        message: res.message,
      };
    } else {
      return {
        status: "error",
        message: res.message,
      };
    }
  };

  /**
   *
   * @param _workspaceMeta - workspace meta data
   * @param path - request stack path
   * @param tabName - request name
   * @param description - request description
   * @param type - save over all request or description only
   */
  public saveAsSocketIo = async (
    _workspaceMeta: {
      id: string;
      name: string;
    },
    path: {
      name: string;
      id: string;
      type: string;
    }[],
    tabName: string,
    description: string,
    componentData: Tab,
  ) => {
    let userSource = {};
    // const _id = componentData.id;
    if (path.length > 0) {
      const socketTabAdapter = new SocketIoTabAdapter();
      const unadaptedSocket = socketTabAdapter.unadapt(componentData);
      const req = {
        id: uuidv4(),
        name: tabName,
        description,
        type: ItemType.SOCKET_IO,
        socketio: unadaptedSocket,
        source: "USER",
        isDeleted: false,
        createdBy: "Guest User",
        updatedBy: "Guest User",
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
      };
      if (path[path.length - 1].type === ItemType.COLLECTION) {
        /**
         * handle request at collection level
         */
        const _collection = await this.readCollection(path[path.length - 1].id);
        if (_collection?.activeSync) {
          userSource = {
            currentBranch: _collection?.currentBranch,
            source: "USER",
          };
        }
        let isGuestUser;
        isGuestUserActive.subscribe((value) => {
          isGuestUser = value;
        });

        if (isGuestUser == true) {
          this.addRequestOrFolderInCollection(path[path.length - 1].id, req);

          return {
            status: "success",
            message: "success",
            data: {
              id: req.id,
            },
          };
        }
        const baseUrl = await this.constructBaseUrl(_workspaceMeta.id);
        const res = await this.collectionService.addSocketIoInCollection(
          {
            collectionId: path[path.length - 1].id,
            workspaceId: _workspaceMeta.id,
            ...userSource,
            items: {
              name: tabName,
              description,
              type: CollectionItemTypeBaseEnum.SOCKETIO,
              socketio: {
                url: unadaptedSocket.url,
                message: unadaptedSocket.message,
                eventName: unadaptedSocket.eventName,
                events: unadaptedSocket.events,
                queryParams: unadaptedSocket.queryParams,
                headers: unadaptedSocket.headers,
                selectedSocketIOBodyType:
                  unadaptedSocket.selectedSocketIOBodyType,
              },
            },
          },
          baseUrl,
        );
        if (res.isSuccessful) {
          this.addRequestOrFolderInCollection(
            path[path.length - 1].id,
            res.data.data,
          );

          return {
            status: "success",
            message: res.message,
            data: {
              id: res.data.data.id,
            },
          };
        } else {
          return {
            status: "error",
            message: res.message,
          };
        }
      } else if (path[path.length - 1].type === ItemType.FOLDER) {
        /**
         * handle request at folder level
         */
        const _collection = await this.readCollection(path[0].id);
        if (_collection?.activeSync) {
          userSource = {
            currentBranch: _collection?.currentBranch,
            source: "USER",
          };
        }
        let isGuestUser;
        isGuestUserActive.subscribe((value) => {
          isGuestUser = value;
        });

        if (isGuestUser == true) {
          this.collectionRepository.addRequestInFolder(
            path[0].id,
            path[path.length - 1].id,
            req,
          );
          return {
            status: "success",
            message: "success",
            data: {
              id: req.id,
            },
          };
        }
        const baseUrl = await this.constructBaseUrl(_workspaceMeta.id);
        const res = await this.collectionService.addSocketIoInCollection(
          {
            collectionId: path[0].id,
            workspaceId: _workspaceMeta.id,
            folderId: path[path.length - 1].id,
            ...userSource,
            items: {
              id: path[path.length - 1].id,
              name: path[path.length - 1].name,
              type: CollectionItemTypeBaseEnum.FOLDER,
              items: {
                name: tabName,
                description,
                type: CollectionItemTypeBaseEnum.SOCKETIO,
                socketio: {
                  url: unadaptedSocket.url,
                  message: unadaptedSocket.message,
                  eventName: unadaptedSocket.eventName,
                  events: unadaptedSocket.events,
                  queryParams: unadaptedSocket.queryParams,
                  headers: unadaptedSocket.headers,
                  selectedSocketIOBodyType:
                    unadaptedSocket.selectedSocketIOBodyType,
                },
              },
            },
          },
          baseUrl,
        );
        if (res.isSuccessful) {
          this.collectionRepository.addRequestInFolder(
            path[0].id,
            path[path.length - 1].id,
            res.data.data,
          );
          return {
            status: "success",
            message: res.message,
            data: {
              id: res.data.data.id,
            },
          };
        } else {
          return {
            status: "error",
            message: res.message,
          };
        }
      }
      MixpanelEvent(Events.SAVE_API_REQUEST);
    }
  };

  /**
   *
   * @param _workspaceMeta - workspace meta data.
   * @param path - request stack path.
   * @param tabName - request name.
   * @param description - request description.
   * @param componentData - GraphQL request tab data.
   */
  public saveAsGraphql = async (
    _workspaceMeta: {
      id: string;
      name: string;
    },
    path: {
      name: string;
      id: string;
      type: string;
    }[],
    tabName: string,
    description: string,
    componentData: Tab,
  ) => {
    let userSource = {};
    if (path.length > 0) {
      const graphqlTabAdapter = new GraphqlTabAdapter();
      const unadaptedRequest = graphqlTabAdapter.unadapt(componentData as Tab);
      let req = {
        id: uuidv4(),
        name: tabName,
        description,
        type: ItemType.GRAPHQL,
        graphql: unadaptedRequest,
        source: "USER",
        isDeleted: false,
        createdBy: "Guest User",
        updatedBy: "Guest User",
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
      };
      if (path[path.length - 1].type === ItemType.COLLECTION) {
        /**
         * handle request at collection level
         */
        const _collection = await this.readCollection(path[path.length - 1].id);
        if (_collection?.activeSync) {
          userSource = {
            currentBranch: _collection?.currentBranch,
            source: "USER",
          };
        }
        const isGuestUser = await this.getGuestUserState();

        if (isGuestUser == true) {
          this.addRequestOrFolderInCollection(path[path.length - 1].id, req);
          return {
            status: "success",
            message: "success",
            data: {
              id: req.id,
            },
          };
        }
        const baseUrl = await this.constructBaseUrl(_workspaceMeta.id);
        const res = await this.collectionService.addGraphqlInCollection(
          {
            collectionId: path[path.length - 1].id,
            workspaceId: _workspaceMeta.id,
            ...userSource,
            items: {
              name: tabName,
              description,
              type: CollectionItemTypeBaseEnum.GRAPHQL,
              graphql: unadaptedRequest,
            },
          },
          baseUrl,
        );
        if (res.isSuccessful) {
          this.addRequestOrFolderInCollection(
            path[path.length - 1].id,
            res.data.data,
          );
          return {
            status: "success",
            message: res.message,
            data: {
              id: res.data.data.id,
            },
          };
        } else {
          return {
            status: "error",
            message: res.message,
          };
        }
      } else if (path[path.length - 1].type === ItemType.FOLDER) {
        /**
         * handle request at folder level
         */
        const _collection = await this.readCollection(path[0].id);
        if (_collection?.activeSync) {
          userSource = {
            currentBranch: _collection?.currentBranch,
            source: "USER",
          };
        }
        const isGuestUser = await this.getGuestUserState();

        if (isGuestUser == true) {
          this.collectionRepository.addRequestInFolder(
            path[0].id,
            path[path.length - 1].id,
            req,
          );
          return {
            status: "success",
            message: "success",
            data: {
              id: req.id,
            },
          };
        }
        const baseUrl = await this.constructBaseUrl(_workspaceMeta.id);
        const res = await this.collectionService.addGraphqlInCollection(
          {
            collectionId: path[0].id,
            workspaceId: _workspaceMeta.id,
            folderId: path[path.length - 1].id,
            ...userSource,
            items: {
              id: path[path.length - 1].id,
              type: CollectionItemTypeBaseEnum.FOLDER,
              name: path[path.length - 1].name,
              items: {
                name: tabName,
                description,
                type: CollectionItemTypeBaseEnum.GRAPHQL,
                graphql: unadaptedRequest,
              },
            },
          },
          baseUrl,
        );
        if (res.isSuccessful) {
          this.collectionRepository.addRequestInFolder(
            path[0].id,
            path[path.length - 1].id,
            res.data.data,
          );

          return {
            status: "success",
            message: res.message,
            data: {
              id: res.data.data.id,
            },
          };
        } else {
          return {
            status: "error",
            message: res.message,
          };
        }
      }
      MixpanelEvent(Events.Save_GraphQL_Request);
    }
  };

  /**
   * Save saveGraphql Request
   * @param graphqlTabData - refers save overall graphql tab data
   * @returns save status
   */
  public saveGraphql = async (graphqlTabData: Tab) => {
    MixpanelEvent(Events.Save_GraphQL_Request);
    const { folderId, collectionId, workspaceId } = graphqlTabData.path as Path;

    if (!workspaceId || !collectionId) {
      return {
        status: "error",
        message: "request is not a part of any workspace or collection",
      };
    }

    const graphqlTabAdapter = new GraphqlTabAdapter();
    const unadaptedRequest = graphqlTabAdapter.unadapt(graphqlTabData as Tab);

    const isGuestUser = await this.getGuestUserState();
    /**
     * Handle save GraphQL Request for guest user
     */
    if (isGuestUser) {
      const guestGraphqlRequest = {
        id: graphqlTabData.id,
        name: graphqlTabData.name,
        description: graphqlTabData.description,
        type: CollectionItemTypeBaseEnum.GRAPHQL,
        graphql: {
          url: unadaptedRequest.url as string,
          query: unadaptedRequest.query,
          schema: unadaptedRequest.schema,
          headers: unadaptedRequest.headers,
          auth: unadaptedRequest.auth,
          selectedGraphqlAuthType: unadaptedRequest.selectedGraphqlAuthType,
        },
        updatedAt: "",
        updatedBy: "Guest User",
      };
      if (!folderId) {
        this.collectionRepository.updateRequestOrFolderInCollection(
          collectionId,
          graphqlTabData.id as string,
          guestGraphqlRequest,
        );
      } else {
        this.collectionRepository.updateRequestInFolder(
          collectionId,
          folderId,
          graphqlTabData.id as string,
          guestGraphqlRequest,
        );
      }
      return {
        status: "success",
        message: "",
      };
    }

    /**
     * Handle save GraphQL Request for registered user
     */

    const graphqlPayload = {
      name: graphqlTabData?.name as string,
      description: graphqlTabData?.description as string,
      url: unadaptedRequest.url as string,
      query: unadaptedRequest.query,
      schema: unadaptedRequest.schema,
      headers: unadaptedRequest.headers,
      auth: unadaptedRequest.auth,
      variables: unadaptedRequest.variables,
      selectedGraphqlAuthType: unadaptedRequest.selectedGraphqlAuthType,
    };
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const res = await this.collectionService.updateGraphqlInCollection(
      graphqlTabData.id as string,
      collectionId,
      workspaceId,
      graphqlPayload,
      baseUrl,
      folderId,
    );

    if (res.isSuccessful) {
      if (!folderId) {
        this.collectionRepository.updateRequestOrFolderInCollection(
          collectionId,
          graphqlTabData.id as string,
          res.data.data,
        );
      } else {
        this.collectionRepository.updateRequestInFolder(
          collectionId,
          folderId,
          graphqlTabData.id as string,
          res.data.data,
        );
      }
      return {
        status: "success",
        message: res.message,
      };
    } else {
      return {
        status: "error",
        message: res.message,
      };
    }
  };

  /**
   * Validates a localhost URL by making a GET request.
   *
   * @param url - The localhost URL to validate.
   * @returns A promise that resolves with the response of the validation request.
   */
  public getOapiJsonFromURL = async (url: string) => {
    const response =
      await this.collectionService.validateImportCollectionURL(url);
    return response;
  };

  /**
   * Validate the data if it follows Open API Specification or not.
   * @param data - Open API Text Data
   * @returns A promise that resolves with the response of the validation request.
   */
  public validateOapiDataSyntax = async (data: any) => {
    const response = await this.collectionService.validateImportCollectionInput(
      "",
      data?.data?.body,
    );
    return response;
  };

  public validateOapiFileSyntax = async (_fileUploadData: any) => {
    const response =
      await this.collectionService.validateImportCollectionFileUpload(
        "",
        _fileUploadData,
      );
    return response;
  };

  // parsing from backend to frontend
  private setResponseBodyType = (header: HttpResponseSavedBodyModeBaseEnum) => {
    let responseBodyNavigation = RequestDatasetEnum.RAW;
    let responseBodyLanguage = RequestDataTypeEnum.TEXT;
    switch (header) {
      case HttpResponseSavedBodyModeBaseEnum.JSON:
        responseBodyNavigation = RequestDatasetEnum.RAW;
        responseBodyLanguage = RequestDataTypeEnum.JSON;
        break;
      case HttpResponseSavedBodyModeBaseEnum.XML:
        responseBodyNavigation = RequestDatasetEnum.RAW;
        responseBodyLanguage = RequestDataTypeEnum.XML;
        break;
      case HttpResponseSavedBodyModeBaseEnum.JAVASCRIPT:
        responseBodyNavigation = RequestDatasetEnum.RAW;
        responseBodyLanguage = RequestDataTypeEnum.JAVASCRIPT;
        break;
      case HttpResponseSavedBodyModeBaseEnum.TEXT:
        responseBodyNavigation = RequestDatasetEnum.RAW;
        responseBodyLanguage = RequestDataTypeEnum.TEXT;
        break;
      case HttpResponseSavedBodyModeBaseEnum.HTML:
        responseBodyNavigation = RequestDatasetEnum.RAW;
        responseBodyLanguage = RequestDataTypeEnum.HTML;
        break;
    }
    return { responseBodyLanguage, responseBodyNavigation };
  };

  /**
   * Saves saved http request
   * @param componentData - refers overall saved request tab data.
   * @returns status of the operation performed.
   */
  private getResponseBodyType = (
    bodyType: RequestDataTypeEnum | RequestDatasetEnum,
  ) => {
    let contentType = HttpResponseSavedBodyModeBaseEnum.TEXT;
    switch (bodyType) {
      case RequestDataTypeEnum.JSON:
        contentType = HttpResponseSavedBodyModeBaseEnum.JSON;
        break;
      case RequestDataTypeEnum.XML:
        contentType = HttpResponseSavedBodyModeBaseEnum.XML;
        break;
      case RequestDataTypeEnum.HTML:
        contentType = HttpResponseSavedBodyModeBaseEnum.HTML;
        break;
      case RequestDataTypeEnum.JAVASCRIPT:
        contentType = HttpResponseSavedBodyModeBaseEnum.JAVASCRIPT;
        break;
      case RequestDataTypeEnum.TEXT:
        contentType = HttpResponseSavedBodyModeBaseEnum.TEXT;
        break;
    }
    return contentType;
  };

  public saveSavedRequest = async (componentData: Tab): Promise<boolean> => {
    const { folderId, collectionId, workspaceId, requestId } =
      componentData.path;
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });

    const responeBodyType = this.getResponseBodyType(
      componentData.property.savedRequest.state.responseBodyLanguage,
    );

    if (isGuestUser === true) {
      if (folderId) {
        this.collectionRepository.updateSavedRequestInFolder(
          collectionId,
          folderId,
          requestId,
          componentData.id,
          {
            description: componentData.description,
            requestResponse: {
              selectedResponseBodyType: responeBodyType,
            },
          },
        );
      } else {
        this.collectionRepository.updateSavedRequestInCollection(
          collectionId,
          requestId,
          componentData.id,
          {
            description: componentData.description,
            requestResponse: {
              selectedResponseBodyType: responeBodyType,
            },
          },
        );
      }
      notifications.success("Response saved successfully.");
      return true;
    }
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const res = await this.collectionService.updateSavedRequestInCollection(
      componentData.id,
      {
        collectionId: collectionId,
        workspaceId: workspaceId,
        requestId: requestId,
        folderId: folderId,
        description: componentData.description,
        selectedResponseBodyType: responeBodyType,
      },
      baseUrl,
    );

    if (res.isSuccessful) {
      if (folderId) {
        this.collectionRepository.updateSavedRequestInFolder(
          collectionId,
          folderId,
          requestId,
          componentData.id,
          {
            description: componentData.description,
            requestResponse: {
              selectedResponseBodyType: responeBodyType,
            },
          },
        );
      } else {
        this.collectionRepository.updateSavedRequestInCollection(
          collectionId,
          requestId,
          componentData.id,
          {
            description: componentData.description,
            requestResponse: {
              selectedResponseBodyType: responeBodyType,
            },
          },
        );
      }
      notifications.success("Response saved successfully.");
      return true;
    } else {
      notifications.error("Failed to save response. Please try again.");
      return false;
    }
  };

  /**
   *
   * @param componentData - saves the folder on tab close.
   */
  public saveFolder = async (componentData: Tab): Promise<boolean> => {
    const progressiveTab = componentData;
    let isGuestUser;
    isGuestUserActive.subscribe((value) => {
      isGuestUser = value;
    });
    if (isGuestUser == true) {
      await this.collectionRepository.updateRequestOrFolderInCollection(
        progressiveTab?.path?.collectionId as string,
        progressiveTab.id,
        {
          description: progressiveTab.description,
          name: progressiveTab.name,
        },
      );
      notifications.success(
        `The ‘${progressiveTab.name}’ folder saved successfully.`,
      );
      return true;
    }
    const baseUrl = await this.constructBaseUrl(
      progressiveTab.path.workspaceId,
    );
    const response = await this.collectionService.updateFolderInCollection(
      progressiveTab.path.workspaceId as string,
      progressiveTab.path.collectionId as string,
      progressiveTab.id as string,
      {
        description: progressiveTab.description,
        name: progressiveTab.name,
      },
      baseUrl,
    );
    if (response.isSuccessful) {
      this.collectionRepository.updateRequestOrFolderInCollection(
        progressiveTab.path.collectionId as string,
        progressiveTab.id as string,
        response.data.data,
      );
      notifications.success(
        `‘${progressiveTab.name}’ folder saved successfully.`,
      );
      return true;
    } else {
      notifications.error("Failed to save folder. Please try again.");
    }
    return false;
  };

  /**
   * Handles saving a collection
   */
  public saveCollection = async (componentData: Tab) => {
    const progressiveTab = createDeepCopy(componentData);
    const guestUser = await this.guestUserRepository.findOne({
      name: "guestUser",
    });
    const isGuestUser = guestUser?.getLatest().toMutableJSON().isGuestUser;
    if (isGuestUser == true) {
      await this.collectionRepository.updateCollection(progressiveTab.id, {
        description: progressiveTab.description,
        name: progressiveTab.name,
        auth: progressiveTab.property.collection.auth,
        selectedAuthType:
          progressiveTab.property.collection.state.collectionAuthNavigation,
      });
      notifications.success(
        `The ‘${progressiveTab.name}’ collection saved successfully.`,
      );
      return true;
    }
    const baseUrl = await this.constructBaseUrl(
      progressiveTab.path.workspaceId,
    );
    const response = await this.collectionService.updateCollectionData(
      progressiveTab.id as string,
      progressiveTab.path.workspaceId as string,
      {
        description: progressiveTab.description,
        name: progressiveTab.name,
        auth: progressiveTab.property.collection.auth,
        selectedAuthType:
          progressiveTab.property.collection.state.collectionAuthNavigation,
      },
      baseUrl,
    );
    const isMockCollection =
      response.data.data?.collectionType === CollectionTypeBaseEnum.MOCK;
    if (response.isSuccessful) {
      this.collectionRepository.updateCollection(
        progressiveTab.id as string,
        response.data.data,
      );
      const successMessage = isMockCollection
        ? `'${progressiveTab.name}' mock collection saved successfully.`
        : `The '${progressiveTab.name}' collection saved successfully.`;

      notifications.success(successMessage);
      return true;
    } else {
      const errorMessage = isMockCollection
        ? `Failed to save mock collection. Please try again.`
        : `Failed to update description. Please try again.`;
      notifications.error(errorMessage);
    }
    return false;
  };

  private constructBaseUrl = async (_id: string) => {
    const workspaceData = await this.workspaceRepository.readWorkspace(_id);
    const hubUrl = workspaceData?.team?.hubUrl;

    const [selfhostBackendUrl] = getSelfhostUrls();
    if (selfhostBackendUrl) {
      return selfhostBackendUrl;
    }

    if (hubUrl && constants.APP_ENVIRONMENT_PATH !== "local") {
      const envSuffix = constants.APP_ENVIRONMENT_PATH;
      return `${hubUrl}/${envSuffix}`;
    }
    return constants.API_URL;
  };

  /**
   * Saves and closes the workspace tab.
   * @param _tab - The tab that is going to be removed.
   */
  public saveWorkspace = async (_tab: Tab): Promise<boolean> => {
    const progressiveTab = createDeepCopy(_tab);
    const baseUrl = await this.constructBaseUrl(progressiveTab.id);
    const response = await this.workspaceService.updateWorkspace(
      progressiveTab.id,
      {
        name: progressiveTab.name,
        description: progressiveTab.description,
      },
      baseUrl,
    );

    if (response.isSuccessful) {
      const updatedata = {
        name: progressiveTab.name,
        description: progressiveTab.description,
        updatedAt: response.data.data.updatedAt,
      };
      await this.workspaceRepository.updateWorkspace(
        progressiveTab.id,
        updatedata,
      );
      notifications.success(
        `The ‘${progressiveTab.name}’ workspace saved successfully.`,
      );
      return true;
    } else {
      notifications.error("Failed to save workspace. Please try again.");
    }
    return false;
  };

  /**
   * Update the tab type to permanent on double click
   * @param tab tab data to make it permanent
   */
  public handleTabTypeChange = async (tab: Tab) => {
    if (tab.persistence === TabPersistenceTypeEnum.TEMPORARY) {
      await this.tabRepository.updateTab(tab.tabId, {
        persistence: TabPersistenceTypeEnum.PERMANENT,
      });
    }
  };

  private compareApisByOperationId = async (existingJson, newJson) => {
    function flattenRequestsByOperationId(json) {
      const requests = {};

      function recurse(items) {
        for (const item of items) {
          if (item.type === ItemType.REQUEST) {
            const key = item.operationId || item.name;
            if (key) {
              requests[key] = item.request || {};
            }
          }
          if (item.items) {
            recurse(item.items);
          }
        }
      }

      recurse(json.items || []);
      return requests;
    }

    function areRequestsDifferent(reqA, reqB) {
      const keysToCompare = [
        "method",
        "url",
        "headers",
        "body",
        "queryParams",
        "auth",
      ];

      for (const key of keysToCompare) {
        const a = reqA[key] ?? null;
        const b = reqB[key] ?? null;

        if (JSON.stringify(a) !== JSON.stringify(b)) {
          return true; // Different
        }
      }
      return false; // Same
    }

    const oldRequests = flattenRequestsByOperationId(existingJson);
    const newRequests = flattenRequestsByOperationId(newJson);

    const added = [];
    const deleted = [];
    const modified = [];

    const oldOps = new Set(Object.keys(oldRequests));
    const newOps = new Set(Object.keys(newRequests));

    // Added & Modified
    for (const opId of newOps) {
      if (!oldOps.has(opId)) {
        added.push(opId);
      } else {
        if (areRequestsDifferent(oldRequests[opId], newRequests[opId])) {
          modified.push(opId);
        }
      }
    }

    // Deleted
    for (const opId of oldOps) {
      if (!newOps.has(opId)) {
        deleted.push(opId);
      }
    }

    const totalOld = oldOps.size;
    const totalChanges = added.length + deleted.length + modified.length;

    let percentChange = 0;
    if (totalOld === 0 && totalChanges > 0) {
      percentChange = 100;
    } else if (totalOld > 0) {
      percentChange = Math.min(100, (totalChanges / totalOld) * 100);
    }

    return {
      addedCount: added.length,
      deletedCount: deleted.length,
      modifiedCount: modified.length,
      percentChange: Number(percentChange.toFixed(1)),
      added,
      deleted,
      modified,
      name: existingJson.name,
      collectionId: existingJson.id,
    };
  };

  public handleCompareCollection = async (collectionId: string) => {
    const collection =
      await this.collectionRepository.readCollection(collectionId);
    if (collection?.activeSyncUrl) {
      const response = await this.getOapiJsonFromURL(collection?.activeSyncUrl);
      const parsedJSON = await this.collectionService.parseOAPIJSONToCollection(
        response?.data?.body,
        ContentTypeEnum["application/json"],
      );
      if (parsedJSON.isSuccessful) {
        const comparisonChanges = await this.compareApisByOperationId(
          collection,
          parsedJSON.data.data,
        );
        return comparisonChanges;
      }
    }
    return {};
  };

  private syncApis = async (
    existingJson,
    newJson,
    modified: string[],
    added: string[],
    deleted: string[],
  ) => {
    const modifiedSet = new Set(modified);
    const addedSet = new Set(added);
    const deletedSet = new Set(deleted);

    const newRequestMap = {};
    const addedRequestMap = {};
    const addedRequestFolderMap: Record<string, string> = {}; // operationId → folder name
    const folderByNameMap: Record<string, any> = {}; // folder name → folder object
    const folderNameSet = new Set<string>();
    const deletedOpSet = new Set(deleted);

    function getRequestKey(item: any): string | null {
      return item.operationId || item.name || null;
    }

    // Step 1: Build maps from newJson (requests & folder names)
    function buildNewMaps(items: any[], currentFolderName = "") {
      for (const item of items) {
        if (item.type === "FOLDER" && item.items) {
          folderByNameMap[item.name] = item; // map folder for potential full insert
          folderNameSet.add(item.name);
          buildNewMaps(item.items, item.name); // recurse into folder
        } else if (item.type === "REQUEST") {
          const key = getRequestKey(item);
          if (!key) continue;
          if (modifiedSet.has(key)) {
            newRequestMap[key] = item;
          }
          if (addedSet.has(key)) {
            addedRequestMap[key] = item;
            addedRequestFolderMap[key] = currentFolderName;
          }
        }
      }
    }
    buildNewMaps(newJson.items || []);

    // Step 2: Modify & Remove in-place
    function updateAndClean(items: any[]): any[] {
      return items.filter((item) => {
        const key = getRequestKey(item);
        if (item.type === "REQUEST" && key && deletedOpSet.has(key)) {
          return false; // Remove
        }

        if (item.type === "REQUEST" && key && modifiedSet.has(key)) {
          const newItem = newRequestMap[key];
          if (newItem) {
            item.request = newItem.request;
            item.name = newItem.name;
            item.description = newItem.description;
          }
        }

        if (item.items) {
          item.items = updateAndClean(item.items);
        }

        return true;
      });
    }

    existingJson.items = updateAndClean(existingJson.items || []);

    // Step 3: Index existing folders by name
    const existingFolderMap: Record<string, any> = {};
    function indexFolders(items: any[]) {
      for (const item of items) {
        if (item.type === "FOLDER") {
          existingFolderMap[item.name] = item;
          if (item.items) indexFolders(item.items);
        }
      }
    }
    indexFolders(existingJson.items || []);

    // Step 4: Add new APIs
    const defaultFolder = existingJson.items.find((i) => i.type === "FOLDER");

    for (const opId of added) {
      const newItem = addedRequestMap[opId];
      const folderName = addedRequestFolderMap[opId];
      const targetFolder = existingFolderMap[folderName];

      if (newItem && targetFolder?.items) {
        targetFolder.items.push(newItem); // Add to existing folder
      } else if (folderName && !existingFolderMap[folderName]) {
        // Folder doesn't exist → add full folder from newJson
        const newFolder = folderByNameMap[folderName];
        if (newFolder) {
          existingJson.items.push(newFolder);
          existingFolderMap[folderName] = newFolder; // Track it now to avoid adding twice
        } else if (defaultFolder?.items) {
          defaultFolder.items.push(newItem); // fallback
        }
      } else if (defaultFolder?.items) {
        defaultFolder.items.push(newItem); // fallback
      }
    }
    // Step 5: Remove folders from existingJson that are not present in newJson
    existingJson.items = existingJson.items.filter((item) => {
      if (item.type === "FOLDER") {
        return folderNameSet.has(item.name); // ✅ Keep only if still exists
      }
      return true; // Keep non-folder items
    });

    return existingJson;
  };

  public syncCollection = async (collectionId: string) => {
    try {
      const collection =
        await this.collectionRepository.readCollection(collectionId);
      if (collection?.activeSyncUrl) {
        const response = await this.getOapiJsonFromURL(
          collection?.activeSyncUrl,
        );
        const parsedJSON =
          await this.collectionService.parseOAPIJSONToCollection(
            response?.data?.body,
            ContentTypeEnum["application/json"],
          );
        const comparisonChanges = await this.compareApisByOperationId(
          collection,
          parsedJSON.data.data,
        );
        const updatedJSONWithSyncedAPIs = await this.syncApis(
          collection.toMutableJSON(),
          parsedJSON.data.data,
          comparisonChanges.modified,
          comparisonChanges.added,
          comparisonChanges.deleted,
        );
        const baseUrl = await this.constructBaseUrl(
          updatedJSONWithSyncedAPIs.workspaceId,
        );
        const apiResponse = await this.collectionService.updateCollectionData(
          collectionId as string,
          updatedJSONWithSyncedAPIs.workspaceId as string,
          {
            items: updatedJSONWithSyncedAPIs.items,
            syncedAt: new Date(),
          },
          baseUrl,
        );
        if (apiResponse.isSuccessful) {
          this.collectionRepository.updateCollection(
            collectionId as string,
            apiResponse.data.data,
          );
          notifications.success(`Collection synced successfully.`);
        } else {
          notifications.error("Failed to sync collection. Please try again.");
        }
      }
    } catch (error) {
      console.error(error);
      notifications.error("Failed to sync collection. Please try again.");
    }
  };

  public replaceCollection = async (collectionId: string) => {
    try {
      const collection =
        await this.collectionRepository.readCollection(collectionId);
      if (collection?.activeSyncUrl) {
        const response = await this.getOapiJsonFromURL(
          collection?.activeSyncUrl,
        );
        const parsedJSON =
          await this.collectionService.parseOAPIJSONToCollection(
            response?.data?.body,
            ContentTypeEnum["application/json"],
          );
        const baseUrl = await this.constructBaseUrl(collection.workspaceId);
        const apiResponse = await this.collectionService.updateCollectionData(
          collectionId as string,
          collection.workspaceId as string,
          {
            items: parsedJSON.data.data.items,
            name: parsedJSON.data.data.name,
            description: parsedJSON.data.data.description,
            syncedAt: new Date(),
          },
          baseUrl,
        );
        if (apiResponse.isSuccessful) {
          this.collectionRepository.updateCollection(
            collectionId as string,
            apiResponse.data.data,
          );
          notifications.success(`Collection replaced successfully.`);
        } else {
          notifications.error(
            "Failed to replace collection. Please try again.",
          );
        }
      }
    } catch (error) {
      console.error(error);
      notifications.error("Failed to replace collection. Please try again.");
    }
  };

  public handleMockCollectionState = async (
    collectionId: string,
    workspaceId: string,
    request: any,
  ) => {
    const baseUrl = await this.constructBaseUrl(workspaceId);
    const response =
      await this.collectionService.updateMockCollectionRunningStatus(
        collectionId,
        workspaceId,

        request,
        baseUrl,
      );
    if (response.isSuccessful) {
      await this.collectionRepository.updateCollection(
        collectionId,
        response.data.data,
      );
    } else if (response.message === "Network Error") {
      notifications.error(response.message);
    } else {
      notifications.error("Failed to update running state. Please try again.");
    }
  };
  public handleOpenWorkspace = async (id: string) => {
    if (!id) return;
    try {
      const res = await this.workspaceRepository.readWorkspace(id);
      const initWorkspaceTab = new WorkspaceTabAdapter().adapt(id, res);
      await this.tabRepository.createTab(initWorkspaceTab, id);
    } catch (error) {
      console.error("Error opening workspace:", error);
      notifications.error("Failed to open workspace. Please try again.");
    }
  };

  public handleCreateMockCollectionFromExisting = async (
    collectionId: string,
    workspaceId: string,
  ) => {
    try {
      const baseUrl = await this.constructBaseUrl(workspaceId);
      const response =
        await this.collectionService.createMockCollectionFromExisting(
          collectionId,
          workspaceId,
          baseUrl,
        );

      if (response.isSuccessful && response.data.data) {
        const res = response.data.data;

        await this.collectionRepository.addCollection({
          ...res,
          id: res._id,
          workspaceId: workspaceId,
          collectionType: CollectionTypeBaseEnum.MOCK,
        });

        const adaptCollection = new CollectionTabAdapter().adapt(workspaceId, {
          ...res,
          id: res._id,
        });
        this.tabRepository.createTab(adaptCollection);
        scrollToTab("");

        await this.workspaceRepository.updateCollectionInWorkspace(
          workspaceId,
          {
            id: res._id,
            name: res.name,
          },
        );

        notifications.success(
          `'${res.name}' mock collection created successfully.`,
        );
      } else {
        notifications.error(
          "Failed to create mock collection. Please try again.",
        );
      }
    } catch (error) {
      console.error("Error creating mock collection from existing:", error);
      notifications.error(
        "Failed to create mock collection. Please try again.",
      );
    }
  };
  public userPlanLimits = async (teamId: string) => {
    const teamDetails = await this.teamRepository.getTeamDoc(teamId);
    const currentPlan = teamDetails?.toMutableJSON().plan;
    if (currentPlan) {
      return currentPlan?.limits;
    }
  };

  public requestToUpgradePlan = async (teamId: string) => {
    const baseUrl = await this.constructBaseUrl(teamId);
    const res = await this.teamService.requestOwnerToUpgradePlan(
      teamId,
      baseUrl,
    );
    if (res?.isSuccessful) {
      notifications.success(
        `Request is Sent Successfully to Owner for Upgrade Plan.`,
      );
    } else {
      notifications.error(`Failed to Send Request for Upgrade Plan`);
    }
  };

  public handleRedirectToAdminPanel = async (teamId: string) => {
    const [authToken] = getAuthJwt();
    const [, , selfhostAdminUrl] = getSelfhostUrls();
    if (selfhostAdminUrl) {
      await open(selfhostAdminUrl);
    } else {
      await open(
        `${constants.ADMIN_URL}/billing/billingOverview/${teamId}?redirectTo=changePlan&xid=${authToken}`,
      );
    }
  };

  public handleContactSales = async () => {
    await open(`${constants.MARKETING_URL}/pricing/`);
  };
}
